From a6ec128cab3c77f7b3241aa9fd971fa19e5d6a3a Mon Sep 17 00:00:00 2001 From: Frederik Ring Date: Thu, 1 Sep 2022 14:38:04 +0200 Subject: [PATCH] Run copying and pruning against multiple storages in parallel (#152) --- cmd/backup/script.go | 32 +++++++++++++++++++++++-------- cmd/backup/stats.go | 2 ++ internal/storage/webdav/webdav.go | 1 - 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/cmd/backup/script.go b/cmd/backup/script.go index 8a33b60..b26fc05 100644 --- a/cmd/backup/script.go +++ b/cmd/backup/script.go @@ -32,6 +32,7 @@ import ( "github.com/otiai10/copy" "github.com/sirupsen/logrus" "golang.org/x/crypto/openpgp" + "golang.org/x/sync/errgroup" ) // script holds all the stateful information required to orchestrate a @@ -493,10 +494,15 @@ func (s *script) copyArchive() error { } } + eg := errgroup.Group{} for _, backend := range s.storages { - if err := backend.Copy(s.file); err != nil { - return err - } + b := backend + eg.Go(func() error { + return b.Copy(s.file) + }) + } + if err := eg.Wait(); err != nil { + return fmt.Errorf("copyArchive: error copying archive: %w", err) } return nil @@ -512,16 +518,26 @@ func (s *script) pruneBackups() error { deadline := time.Now().AddDate(0, 0, -int(s.c.BackupRetentionDays)).Add(s.c.BackupPruningLeeway) + eg := errgroup.Group{} for _, backend := range s.storages { - if stats, err := backend.Prune(deadline, s.c.BackupPruningPrefix); err == nil { - s.stats.Storages[backend.Name()] = StorageStats{ + b := backend + eg.Go(func() error { + stats, err := b.Prune(deadline, s.c.BackupPruningPrefix) + if err != nil { + return err + } + s.stats.Lock() + s.stats.Storages[b.Name()] = StorageStats{ Total: stats.Total, Pruned: stats.Pruned, } + s.stats.Unlock() + return nil + }) + } - } else { - return err - } + if err := eg.Wait(); err != nil { + return fmt.Errorf("pruneBackups: error pruning backups: %w", err) } return nil diff --git a/cmd/backup/stats.go b/cmd/backup/stats.go index fbb5e11..4eed0d9 100644 --- a/cmd/backup/stats.go +++ b/cmd/backup/stats.go @@ -5,6 +5,7 @@ package main import ( "bytes" + "sync" "time" ) @@ -32,6 +33,7 @@ type StorageStats struct { // Stats global stats regarding script execution type Stats struct { + sync.Mutex StartTime time.Time EndTime time.Time TookTime time.Duration diff --git a/internal/storage/webdav/webdav.go b/internal/storage/webdav/webdav.go index 72b06d1..c95c164 100644 --- a/internal/storage/webdav/webdav.go +++ b/internal/storage/webdav/webdav.go @@ -35,7 +35,6 @@ type Config struct { // NewStorageBackend creates and initializes a new WebDav storage backend. func NewStorageBackend(opts Config, logFunc storage.Log) (storage.Backend, error) { - if opts.Username == "" || opts.Password == "" { return nil, errors.New("NewStorageBackend: WEBDAV_URL is defined, but no credentials were provided") } else {