From d4569946c5806aa1e42c34e87f78ede4a80929d8 Mon Sep 17 00:00:00 2001
From: Leonard Lyubich <leonard@nspcc.ru>
Date: Fri, 15 Apr 2022 08:52:24 +0300
Subject: [PATCH] [#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>
---
 cmd/neofs-node/cache.go     | 30 ------------------------------
 cmd/neofs-node/container.go | 19 +------------------
 2 files changed, 1 insertion(+), 48 deletions(-)

diff --git a/cmd/neofs-node/cache.go b/cmd/neofs-node/cache.go
index 111bd1c3b..2fa66c53d 100644
--- a/cmd/neofs-node/cache.go
+++ b/cmd/neofs-node/cache.go
@@ -158,11 +158,6 @@ func (s *ttlContainerStorage) Get(cid *cid.ID) (*containerSDK.Container, error)
 	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
 
 func newCachedEACLStorage(v eacl.Source) *ttlEACLStorage {
@@ -295,31 +290,6 @@ func (s *ttlContainerLister) InvalidateContainerList(id *owner.ID) {
 	(*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
 
 func newCachedIRFetcher(f interface{ InnerRingKeys() ([][]byte, error) }) *cachedIRFetcher {
diff --git a/cmd/neofs-node/container.go b/cmd/neofs-node/container.go
index 15890028e..f458399c9 100644
--- a/cmd/neofs-node/container.go
+++ b/cmd/neofs-node/container.go
@@ -85,7 +85,6 @@ func initContainerService(c *cfg) {
 		cnrWrt.cacheEnabled = true
 		cnrWrt.lists = cachedContainerLister
 		cnrWrt.eacls = cachedEACLStorage
-		cnrWrt.containers = cachedContainerStorage
 	}
 
 	localMetrics := &localStorageLoad{
@@ -564,7 +563,6 @@ type morphContainerWriter struct {
 	neoClient *cntClient.Client
 
 	cacheEnabled bool
-	containers   *ttlContainerStorage
 	eacls        *ttlEACLStorage
 	lists        *ttlContainerLister
 }
@@ -583,22 +581,7 @@ func (m morphContainerWriter) Put(cnr *containerSDK.Container) (*cid.ID, error)
 }
 
 func (m morphContainerWriter) Delete(witness containerCore.RemovalWitness) error {
-	err := 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
+	return cntClient.Delete(m.neoClient, witness)
 }
 
 func (m morphContainerWriter) PutEACL(table *eaclSDK.Table) error {