From 3a48b282b64429149ca7f9770eacb8a5bdc7173a Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 12 Jul 2024 17:16:06 +0300 Subject: [PATCH] [#1248] placement: Use epoch to track netmap versions Previously we used pointer, this could have worked, because most of the time, the netmap is cached. This didn't work, however, because `lastNm` field was always nil. Rework the mechanism completely: 1. Use epoch to track netmap versions, as it it simpler and is unrelated to the TTL of an underlying cache. 2. Fix a bug where the epoch could change while mutex was unlocked. Signed-off-by: Evgenii Stratonikov --- pkg/services/object_manager/placement/netmap.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/pkg/services/object_manager/placement/netmap.go b/pkg/services/object_manager/placement/netmap.go index 41267dbae..8163529ed 100644 --- a/pkg/services/object_manager/placement/netmap.go +++ b/pkg/services/object_manager/placement/netmap.go @@ -14,9 +14,10 @@ import ( type netMapBuilder struct { nmSrc netmap.Source - // mtx protects lastNm and containerCache fields. - mtx sync.Mutex - lastNm *netmapSDK.NetMap + // mtx protects lastEpoch and containerCache fields. + mtx sync.Mutex + // lastEpoch contains contains network map epoch for all values in the container cache. + lastEpoch uint64 // containerCache caches container nodes by ID. It is used to skip `GetContainerNodes` invocation if // neither netmap nor container has changed. containerCache simplelru.LRUCache[cid.ID, [][]netmapSDK.NodeInfo] @@ -61,13 +62,14 @@ func (b *netMapBuilder) BuildPlacement(cnr cid.ID, obj *oid.ID, p netmapSDK.Plac cnr.Encode(binCnr) b.mtx.Lock() - if nm == b.lastNm { + if nm.Epoch() == b.lastEpoch { raw, ok := b.containerCache.Get(cnr) b.mtx.Unlock() if ok { return BuildObjectPlacement(nm, raw, obj) } } else { + b.lastEpoch = nm.Epoch() b.containerCache.Purge() b.mtx.Unlock() } @@ -78,7 +80,9 @@ func (b *netMapBuilder) BuildPlacement(cnr cid.ID, obj *oid.ID, p netmapSDK.Plac } b.mtx.Lock() - b.containerCache.Add(cnr, cn) + if b.lastEpoch == nm.Epoch() { + b.containerCache.Add(cnr, cn) + } b.mtx.Unlock() return BuildObjectPlacement(nm, cn, obj)