[#199] putsvc: Refactor placement iterator

Resolve funlen linter for iteratePlacement method

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
Dmitrii Stepanov 2023-04-03 12:24:01 +03:00 committed by Gitea
parent a69c6d1ec9
commit 14d894178e

View file

@ -164,7 +164,6 @@ func (t *distributedTarget) sendObject(node nodeDesc) error {
return nil return nil
} }
// nolint: funlen
func (t *distributedTarget) iteratePlacement(f func(nodeDesc) error) (*transformer.AccessIdentifiers, error) { func (t *distributedTarget) iteratePlacement(f func(nodeDesc) error) (*transformer.AccessIdentifiers, error) {
id, _ := t.obj.ID() id, _ := t.obj.ID()
@ -175,16 +174,42 @@ func (t *distributedTarget) iteratePlacement(f func(nodeDesc) error) (*transform
return nil, fmt.Errorf("(%T) could not create object placement traverser: %w", t, err) return nil, fmt.Errorf("(%T) could not create object placement traverser: %w", t, err)
} }
var resErr atomic.Value resErr := &atomic.Value{}
loop:
for { for {
addrs := traverser.Next() addrs := traverser.Next()
if len(addrs) == 0 { if len(addrs) == 0 {
break break
} }
wg := new(sync.WaitGroup) if t.iterateAddresses(traverser, addrs, f, resErr) {
break
}
}
if !traverser.Success() {
var err errIncompletePut
err.singleErr, _ = resErr.Load().(error)
return nil, err
}
// perform additional container broadcast if needed
if t.traversal.submitPrimaryPlacementFinish() {
_, err = t.iteratePlacement(f)
if err != nil {
t.log.Error("additional container broadcast failure", zap.Error(err))
// we don't fail primary operation because of broadcast failure
}
}
id, _ = t.obj.ID()
return new(transformer.AccessIdentifiers).
WithSelfID(id), nil
}
func (t *distributedTarget) iterateAddresses(traverser *placement.Traverser, addrs []placement.Node, f func(nodeDesc) error, resErr *atomic.Value) bool {
wg := &sync.WaitGroup{}
for i := range addrs { for i := range addrs {
if t.traversal.processed(addrs[i]) { if t.traversal.processed(addrs[i]) {
@ -195,15 +220,11 @@ loop:
wg.Add(1) wg.Add(1)
addr := addrs[i] addr := addrs[i]
isLocal := t.isLocalKey(addr.PublicKey()) isLocal := t.isLocalKey(addr.PublicKey())
var workerPool util.WorkerPool workerPool := t.remotePool
if isLocal { if isLocal {
workerPool = t.localPool workerPool = t.localPool
} else {
workerPool = t.remotePool
} }
if err := workerPool.Submit(func() { if err := workerPool.Submit(func() {
@ -226,38 +247,12 @@ loop:
traverser.SubmitSuccess() traverser.SubmitSuccess()
}); err != nil { }); err != nil {
wg.Done() wg.Done()
svcutil.LogWorkerPoolError(t.log, "PUT", err) svcutil.LogWorkerPoolError(t.log, "PUT", err)
return true
break loop
} }
} }
wg.Wait() wg.Wait()
}
return false
if !traverser.Success() {
var err errIncompletePut
err.singleErr, _ = resErr.Load().(error)
return nil, err
}
// perform additional container broadcast if needed
if t.traversal.submitPrimaryPlacementFinish() {
_, err = t.iteratePlacement(f)
if err != nil {
t.log.Error("additional container broadcast failure",
zap.Error(err),
)
// we don't fail primary operation because of broadcast failure
}
}
id, _ = t.obj.ID()
return new(transformer.AccessIdentifiers).
WithSelfID(id), nil
} }