diff --git a/cmd/neofs-node/cache.go b/cmd/neofs-node/cache.go index 74cac13e7f..7a5ddff904 100644 --- a/cmd/neofs-node/cache.go +++ b/cmd/neofs-node/cache.go @@ -1,6 +1,7 @@ package main import ( + "sync" "time" lru "github.com/hashicorp/golang-lru" @@ -8,6 +9,7 @@ import ( "github.com/nspcc-dev/neofs-node/pkg/core/netmap" cntClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/container" "github.com/nspcc-dev/neofs-node/pkg/services/object/acl/eacl" + putsvc "github.com/nspcc-dev/neofs-node/pkg/services/object/put" containerSDK "github.com/nspcc-dev/neofs-sdk-go/container" cid "github.com/nspcc-dev/neofs-sdk-go/container/id" eaclSDK "github.com/nspcc-dev/neofs-sdk-go/eacl" @@ -325,3 +327,40 @@ func (f *cachedIRFetcher) InnerRingKeys() ([][]byte, error) { return val.([][]byte), nil } + +type ttlMaxObjectSizeCache struct { + mtx sync.RWMutex + lastUpdated time.Time + lastSize uint64 + src putsvc.MaxSizeSource +} + +func newCachedMaxObjectSizeSource(src putsvc.MaxSizeSource) putsvc.MaxSizeSource { + return &ttlMaxObjectSizeCache{ + src: src, + } +} + +func (c *ttlMaxObjectSizeCache) MaxObjectSize() uint64 { + const ttl = time.Second * 30 + + c.mtx.RLock() + prevUpdated := c.lastUpdated + size := c.lastSize + c.mtx.RUnlock() + + if time.Since(prevUpdated) < ttl { + return size + } + + c.mtx.Lock() + size = c.lastSize + if !c.lastUpdated.After(prevUpdated) { + size = c.src.MaxObjectSize() + c.lastSize = size + c.lastUpdated = time.Now() + } + c.mtx.Unlock() + + return size +} diff --git a/cmd/neofs-node/object.go b/cmd/neofs-node/object.go index df44496dde..6a65d9ab40 100644 --- a/cmd/neofs-node/object.go +++ b/cmd/neofs-node/object.go @@ -271,7 +271,7 @@ func initObjectService(c *cfg) { sPut := putsvc.NewService( putsvc.WithKeyStorage(keyStorage), putsvc.WithClientConstructor(coreConstructor), - putsvc.WithMaxSizeSource(c), + putsvc.WithMaxSizeSource(newCachedMaxObjectSizeSource(c)), putsvc.WithObjectStorage(os), putsvc.WithContainerSource(c.cfgObject.cnrSource), putsvc.WithNetworkMapSource(c.netMapSource),