[#1313] container: Do not invalidate cache on Container.Delete

In previous implementation `Container.Delete` operation caused local
node's cache invalidation (container itself, eACL and listings). Any
subsequent `Container.Get` operation reversed invalidation. Given the
low latency sensitivity of deleting a container, there is no need to
touch the cache. With this approach, all pending deletion operations on
the node via the NeoFS API protocol will be delayed by the cache TTL.

Do not call cache invalidation ops in `morphContainerWriter.Delete`.
Remove no longer needed `InvalidateContainerListByCID` and
`InvalidateContainer` methods.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2022-04-15 08:52:24 +03:00 committed by LeL
parent 606dfa3414
commit d4569946c5
2 changed files with 1 additions and 48 deletions

View file

@ -158,11 +158,6 @@ func (s *ttlContainerStorage) Get(cid *cid.ID) (*containerSDK.Container, error)
return val.(*containerSDK.Container), nil return val.(*containerSDK.Container), nil
} }
// InvalidateContainer removes cached container value.
func (s *ttlContainerStorage) InvalidateContainer(cid *cid.ID) {
(*ttlNetCache)(s).remove(cid.String())
}
type ttlEACLStorage ttlNetCache type ttlEACLStorage ttlNetCache
func newCachedEACLStorage(v eacl.Source) *ttlEACLStorage { func newCachedEACLStorage(v eacl.Source) *ttlEACLStorage {
@ -295,31 +290,6 @@ func (s *ttlContainerLister) InvalidateContainerList(id *owner.ID) {
(*ttlNetCache)(s).remove(id.String()) (*ttlNetCache)(s).remove(id.String())
} }
// InvalidateContainerListByCID removes cached list of container IDs. To do that
// function iterates over all available lists and removes the first list where
// specified ID is present.
func (s *ttlContainerLister) InvalidateContainerListByCID(id *cid.ID) {
cache := (*ttlNetCache)(s)
for _, key := range cache.keys() {
val, err := cache.get(key)
if err != nil {
continue
}
ids, ok := val.([]*cid.ID)
if !ok {
continue
}
for i := range ids {
if ids[i].Equal(id) {
cache.remove(key)
return
}
}
}
}
type cachedIRFetcher ttlNetCache type cachedIRFetcher ttlNetCache
func newCachedIRFetcher(f interface{ InnerRingKeys() ([][]byte, error) }) *cachedIRFetcher { func newCachedIRFetcher(f interface{ InnerRingKeys() ([][]byte, error) }) *cachedIRFetcher {

View file

@ -85,7 +85,6 @@ func initContainerService(c *cfg) {
cnrWrt.cacheEnabled = true cnrWrt.cacheEnabled = true
cnrWrt.lists = cachedContainerLister cnrWrt.lists = cachedContainerLister
cnrWrt.eacls = cachedEACLStorage cnrWrt.eacls = cachedEACLStorage
cnrWrt.containers = cachedContainerStorage
} }
localMetrics := &localStorageLoad{ localMetrics := &localStorageLoad{
@ -564,7 +563,6 @@ type morphContainerWriter struct {
neoClient *cntClient.Client neoClient *cntClient.Client
cacheEnabled bool cacheEnabled bool
containers *ttlContainerStorage
eacls *ttlEACLStorage eacls *ttlEACLStorage
lists *ttlContainerLister lists *ttlContainerLister
} }
@ -583,22 +581,7 @@ func (m morphContainerWriter) Put(cnr *containerSDK.Container) (*cid.ID, error)
} }
func (m morphContainerWriter) Delete(witness containerCore.RemovalWitness) error { func (m morphContainerWriter) Delete(witness containerCore.RemovalWitness) error {
err := cntClient.Delete(m.neoClient, witness) return cntClient.Delete(m.neoClient, witness)
if err != nil {
return err
}
if m.cacheEnabled {
containerID := witness.ContainerID()
m.containers.InvalidateContainer(containerID)
m.eacls.InvalidateEACL(containerID)
// it is faster to use slower invalidation by CID than making separate
// network request to fetch owner ID of the container.
m.lists.InvalidateContainerListByCID(containerID)
}
return nil
} }
func (m morphContainerWriter) PutEACL(table *eaclSDK.Table) error { func (m morphContainerWriter) PutEACL(table *eaclSDK.Table) error {