[#2037] services/object: Fix concurrent map writes in traverser
``` fatal error: concurrent map writes goroutine 4337 [running]: github.com/nspcc-dev/neofs-node/pkg/services/object/put.(*traversal).submitProcessed(...) github.com/nspcc-dev/neofs-node/pkg/services/object/put/distributed.go:78 github.com/nspcc-dev/neofs-node/pkg/services/object/put.(*distributedTarget).iteratePlacement.func1() github.com/nspcc-dev/neofs-node/pkg/services/object/put/distributed.go:198 +0x265 github.com/panjf2000/ants/v2.(*goWorker).run.func1() github.com/panjf2000/ants/v2@v2.4.0/worker.go:68 +0x97 created by github.com/panjf2000/ants/v2.(*goWorker).run github.com/panjf2000/ants/v2@v2.4.0/worker.go:48 +0x65 ``` Signed-off-by: Evgenii Stratonikov <evgeniy@morphbits.ru>
This commit is contained in:
parent
37f813604f
commit
2522d924b9
2 changed files with 12 additions and 2 deletions
|
@ -21,6 +21,7 @@ Changelog for NeoFS Node
|
|||
- `neofs-cli lock object`'s `lifetime` flag handling (#1972)
|
||||
- Do not move write-cache in read-only mode for flushing (#1906)
|
||||
- Child object collection on CLI side with a bearer token (#2000)
|
||||
- Fix concurrent map writes in `Object.Put` service
|
||||
|
||||
### Removed
|
||||
### Updated
|
||||
|
|
|
@ -48,6 +48,9 @@ type traversal struct {
|
|||
// need of additional broadcast after the object is saved
|
||||
extraBroadcastEnabled bool
|
||||
|
||||
// mtx protects mExclude map.
|
||||
mtx sync.RWMutex
|
||||
|
||||
// container nodes which was processed during the primary object placement
|
||||
mExclude map[string]struct{}
|
||||
}
|
||||
|
@ -71,17 +74,23 @@ func (x *traversal) submitPrimaryPlacementFinish() bool {
|
|||
// marks the container node as processed during the primary object placement.
|
||||
func (x *traversal) submitProcessed(n placement.Node) {
|
||||
if x.extraBroadcastEnabled {
|
||||
key := string(n.PublicKey())
|
||||
|
||||
x.mtx.Lock()
|
||||
if x.mExclude == nil {
|
||||
x.mExclude = make(map[string]struct{}, 1)
|
||||
}
|
||||
|
||||
x.mExclude[string(n.PublicKey())] = struct{}{}
|
||||
x.mExclude[key] = struct{}{}
|
||||
x.mtx.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
// checks if specified node was processed during the primary object placement.
|
||||
func (x traversal) processed(n placement.Node) bool {
|
||||
func (x *traversal) processed(n placement.Node) bool {
|
||||
x.mtx.RLock()
|
||||
_, ok := x.mExclude[string(n.PublicKey())]
|
||||
x.mtx.RUnlock()
|
||||
return ok
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue