From 72c044e2eb553abf0e0fd7eb87043176f23400f0 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Wed, 8 Jun 2022 14:03:29 +0300 Subject: [PATCH] [#1599] engine: Parallelize shard initialization Shard is intended to be used as a separate failure domain, which usually resides on a separate disk. Thus, sequential initialization is bound by IO and this change speeds up thing a bit. Signed-off-by: Evgenii Stratonikov --- pkg/local_object_storage/engine/control.go | 40 +++++++++++++++++++--- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/pkg/local_object_storage/engine/control.go b/pkg/local_object_storage/engine/control.go index f5753651..4fc39da8 100644 --- a/pkg/local_object_storage/engine/control.go +++ b/pkg/local_object_storage/engine/control.go @@ -3,7 +3,9 @@ package engine import ( "errors" "fmt" + "sync" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard" "go.uber.org/zap" ) @@ -16,9 +18,24 @@ func (e *StorageEngine) open() error { e.mtx.RLock() defer e.mtx.RUnlock() + var wg sync.WaitGroup + var errCh = make(chan error, len(e.shards)) + for id, sh := range e.shards { - if err := sh.Open(); err != nil { - return fmt.Errorf("could not open shard %s: %w", id, err) + wg.Add(1) + go func(id string, sh *shard.Shard) { + defer wg.Done() + if err := sh.Open(); err != nil { + errCh <- fmt.Errorf("could not open shard %s: %w", id, err) + } + }(id, sh.Shard) + } + wg.Wait() + close(errCh) + + for err := range errCh { + if err != nil { + return err } } @@ -30,9 +47,24 @@ func (e *StorageEngine) Init() error { e.mtx.RLock() defer e.mtx.RUnlock() + var wg sync.WaitGroup + var errCh = make(chan error, len(e.shards)) + for id, sh := range e.shards { - if err := sh.Init(); err != nil { - return fmt.Errorf("could not initialize shard %s: %w", id, err) + wg.Add(1) + go func(id string, sh *shard.Shard) { + defer wg.Done() + if err := sh.Init(); err != nil { + errCh <- fmt.Errorf("could not initialize shard %s: %w", id, err) + } + }(id, sh.Shard) + } + wg.Wait() + close(errCh) + + for err := range errCh { + if err != nil { + return err } }