From 3cf5e1e2a81a8a974c3f3122bcb2d00f03ed7449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Tue, 25 Apr 2023 14:41:36 +0200 Subject: [PATCH] pipeline cache deletes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- changelog/unreleased/pipeline-cache-delete.md | 6 +++ pkg/storage/cache/provider.go | 19 +++++---- pkg/storage/cache/stat.go | 40 ++++++++++--------- 3 files changed, 38 insertions(+), 27 deletions(-) create mode 100644 changelog/unreleased/pipeline-cache-delete.md diff --git a/changelog/unreleased/pipeline-cache-delete.md b/changelog/unreleased/pipeline-cache-delete.md new file mode 100644 index 00000000000..e7b308aa6dc --- /dev/null +++ b/changelog/unreleased/pipeline-cache-delete.md @@ -0,0 +1,6 @@ +Bugfix: Pipeline cache deletes + +The gateway now pipelines deleting keys from the stat and provider cache + +https://github.com/cs3org/reva/pull/3817 +https://github.com/cs3org/reva/pull/3809 \ No newline at end of file diff --git a/pkg/storage/cache/provider.go b/pkg/storage/cache/provider.go index f7ad3e1d061..23b8a3f8240 100644 --- a/pkg/storage/cache/provider.go +++ b/pkg/storage/cache/provider.go @@ -19,11 +19,12 @@ package cache import ( - "strings" + "sync" "time" userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + "go-micro.dev/v4/store" ) // ProviderCache can invalidate all provider related cache entries @@ -47,20 +48,22 @@ func (c providerCache) RemoveListStorageProviders(res *provider.ResourceId) { if res == nil { return } - sid := res.SpaceId - keys, err := c.List() + keys, err := c.List(store.ListSuffix(res.SpaceId), store.ListLimit(100)) if err != nil { // FIXME log error return } - // FIXME add context option to List, Read and Write to upstream + + wg := sync.WaitGroup{} for _, key := range keys { - if strings.Contains(key, sid) { - _ = c.Delete(key) - continue - } + wg.Add(1) + go func(k string) { + defer wg.Done() + _ = c.Delete(k) + }(key) } + wg.Wait() } func (c providerCache) GetKey(userID *userpb.UserId, spaceID string) string { diff --git a/pkg/storage/cache/stat.go b/pkg/storage/cache/stat.go index 414fe77f398..cf990a86396 100644 --- a/pkg/storage/cache/stat.go +++ b/pkg/storage/cache/stat.go @@ -20,10 +20,12 @@ package cache import ( "strings" + "sync" "time" userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + "go-micro.dev/v4/store" ) // NewStatCache creates a new StatCache @@ -50,27 +52,27 @@ func (c statCache) RemoveStat(userID *userpb.UserId, res *provider.ResourceId) { oid = "oid:" + res.OpaqueId } - keys, err := c.List() - if err != nil { - // FIXME handle error - return - } - for _, key := range keys { - if strings.Contains(key, uid) { - _ = c.Delete(key) - continue - } - - if sid != "" && strings.Contains(key, sid) { - _ = c.Delete(key) - continue - } + // TODO currently, invalidating the stat cache is inefficient and should be disabled. Storage providers / drivers can more selectively invalidate stat cache entries. + // This shotgun invalidation wipes all cache entries for the user, space, and nodeid of a changed resource, which means the stat cache is mostly empty, anyway. + prefixes := []string{uid, "*" + sid, "*" + oid} - if oid != "" && strings.Contains(key, oid) { - _ = c.Delete(key) - continue - } + wg := sync.WaitGroup{} + for _, prefix := range prefixes { + wg.Add(1) + go func(p string) { + defer wg.Done() + keys, _ := c.List(store.ListPrefix(p), store.ListLimit(100)) + for _, key := range keys { + wg.Add(1) + go func(k string) { + defer wg.Done() + _ = c.Delete(k) + }(key) + } + }(prefix) } + + wg.Wait() } // generates a user specific key pointing to ref - used for statcache