From f29b4c0994dbbf05dd2d8c1c426d2ccf134e041d Mon Sep 17 00:00:00 2001 From: MaxJa4 <74194322+MaxJa4@users.noreply.github.com> Date: Mon, 21 Aug 2023 14:33:37 +0200 Subject: [PATCH] Fixed some instabilites. Changed default concurrency to 6. --- cmd/backup/config.go | 2 +- internal/storage/dropbox/dropbox.go | 23 ++++++++++++++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/cmd/backup/config.go b/cmd/backup/config.go index b84f90c..4cced0b 100644 --- a/cmd/backup/config.go +++ b/cmd/backup/config.go @@ -72,7 +72,7 @@ type Config struct { AzureStorageEndpoint string `split_words:"true" default:"https://{{ .AccountName }}.blob.core.windows.net/"` DropboxToken string `split_words:"true"` DropboxRemotePath string `split_words:"true"` - DropboxConcurrencyLevel int `split_words:"true" default:"2"` + DropboxConcurrencyLevel int `split_words:"true" default:"6"` } func (c *Config) resolveSecret(envVar string, secretPath string) (string, error) { diff --git a/internal/storage/dropbox/dropbox.go b/internal/storage/dropbox/dropbox.go index 129655a..823fc1f 100644 --- a/internal/storage/dropbox/dropbox.go +++ b/internal/storage/dropbox/dropbox.go @@ -63,9 +63,14 @@ func (b *dropboxStorage) Copy(file string) error { folderArg := files.NewCreateFolderArg(b.DestinationPath) if _, err := b.client.CreateFolderV2(folderArg); err != nil { - if err.(files.CreateFolderV2APIError).EndpointError.Path.Tag == files.WriteErrorConflict { - b.Log(storage.LogLevelInfo, b.Name(), "Destination path '%s' already exists in Dropbox, no new directory required.", b.DestinationPath) - } else { + switch err := err.(type) { + case files.CreateFolderV2APIError: + if err.EndpointError.Path.Tag == files.WriteErrorConflict { + b.Log(storage.LogLevelInfo, b.Name(), "Destination path '%s' already exists in Dropbox, no new directory required.", b.DestinationPath) + } else { + return fmt.Errorf("(*dropboxStorage).Copy: Error creating directory '%s' in Dropbox: %w", b.DestinationPath, err) + } + default: return fmt.Errorf("(*dropboxStorage).Copy: Error creating directory '%s' in Dropbox: %w", b.DestinationPath, err) } } @@ -98,6 +103,7 @@ func (b *dropboxStorage) Copy(file string) error { var errorChn = make(chan error, b.concurrencyLevel) var EOFChn = make(chan bool, b.concurrencyLevel) var mu sync.Mutex + var wg sync.WaitGroup loop: for { @@ -106,12 +112,17 @@ loop: case err := <-errorChn: // error from goroutine return err case <-EOFChn: // EOF from goroutine + wg.Wait() // wait for all goroutines to finish break loop default: } go func() { - defer func() { <-guard }() + defer func() { + wg.Done() + <-guard + }() + wg.Add(1) chunk := make([]byte, chunkSize) mu.Lock() // to preserve offset of chunks @@ -119,13 +130,15 @@ loop: select { case <-EOFChn: EOFChn <- true // put it back for outer loop - return // already EOF + mu.Unlock() + return // already EOF default: } bytesRead, err := r.Read(chunk) if err != nil { errorChn <- fmt.Errorf("(*dropboxStorage).Copy: Error reading the file to be uploaded: %w", err) + mu.Unlock() return } chunk = chunk[:bytesRead]