From d9b3f951574a38e3ad9b9170d39035c72ac687bb Mon Sep 17 00:00:00 2001 From: Ishank Arora Date: Thu, 21 Jan 2021 12:16:16 +0100 Subject: [PATCH] Use updated etag of home directory even if it is cached --- changelog/unreleased/etag-cache-fix.md | 8 +++++ .../grpc/services/gateway/storageprovider.go | 29 +++++++++++++++---- 2 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 changelog/unreleased/etag-cache-fix.md diff --git a/changelog/unreleased/etag-cache-fix.md b/changelog/unreleased/etag-cache-fix.md new file mode 100644 index 0000000000..81dca5ec50 --- /dev/null +++ b/changelog/unreleased/etag-cache-fix.md @@ -0,0 +1,8 @@ +Enhancement: Use updated etag of home directory even if it is cached + +We cache the home directory and shares folder etags as calculating these is an +expensive process. But if these directories were updated after the previously +calculated etag was cached, we can ignore this calculation and directly return +the new one. + +https://github.com/cs3org/reva/pull/1416 diff --git a/internal/grpc/services/gateway/storageprovider.go b/internal/grpc/services/gateway/storageprovider.go index dc78d74b7c..bb52f48c6b 100644 --- a/internal/grpc/services/gateway/storageprovider.go +++ b/internal/grpc/services/gateway/storageprovider.go @@ -37,6 +37,7 @@ import ( "github.com/cs3org/reva/pkg/storage/utils/etag" "github.com/cs3org/reva/pkg/storage/utils/templates" "github.com/cs3org/reva/pkg/user" + "github.com/cs3org/reva/pkg/utils" "github.com/dgrijalva/jwt-go" "github.com/pkg/errors" ) @@ -985,12 +986,17 @@ func (s *svc) statHome(ctx context.Context) (*provider.StatResponse, error) { }, nil } - if resEtag, err := s.etagCache.Get(statRes.Info.Owner.OpaqueId + ":" + statRes.Info.Path); err == nil { - statRes.Info.Etag = resEtag.(string) + if etagIface, err := s.etagCache.Get(statRes.Info.Owner.OpaqueId + ":" + statRes.Info.Path); err == nil { + resMtime := utils.TSToTime(statRes.Info.Mtime) + resEtag := etagIface.(etagWithTS) + // Use the updated etag if the home folder has been modified + if resMtime.Before(resEtag.Timestamp) { + statRes.Info.Etag = resEtag.Etag + } } else { statRes.Info.Etag = etag.GenerateEtagFromResources(statRes.Info, []*provider.ResourceInfo{statSharedFolder.Info}) if s.c.EtagCacheTTL > 0 { - _ = s.etagCache.Set(statRes.Info.Owner.OpaqueId+":"+statRes.Info.Path, statRes.Info.Etag) + _ = s.etagCache.Set(statRes.Info.Owner.OpaqueId+":"+statRes.Info.Path, etagWithTS{statRes.Info.Etag, time.Now()}) } } @@ -1029,12 +1035,18 @@ func (s *svc) statSharesFolder(ctx context.Context) (*provider.StatResponse, err }, nil } - if resEtag, err := s.etagCache.Get(statRes.Info.Owner.OpaqueId + ":" + statRes.Info.Path); err == nil { - statRes.Info.Etag = resEtag.(string) + if etagIface, err := s.etagCache.Get(statRes.Info.Owner.OpaqueId + ":" + statRes.Info.Path); err == nil { + resMtime := utils.TSToTime(statRes.Info.Mtime) + resEtag := etagIface.(etagWithTS) + // Use the updated etag if the shares folder has been modified, i.e., a new + // reference has been created. + if resMtime.Before(resEtag.Timestamp) { + statRes.Info.Etag = resEtag.Etag + } } else { statRes.Info.Etag = etag.GenerateEtagFromResources(statRes.Info, lsRes.Infos) if s.c.EtagCacheTTL > 0 { - _ = s.etagCache.Set(statRes.Info.Owner.OpaqueId+":"+statRes.Info.Path, statRes.Info.Etag) + _ = s.etagCache.Set(statRes.Info.Owner.OpaqueId+":"+statRes.Info.Path, etagWithTS{statRes.Info.Etag, time.Now()}) } } return statRes, nil @@ -1852,3 +1864,8 @@ func (s *svc) getStorageProvider(ctx context.Context, ref *provider.Reference) ( return res.Provider, nil } + +type etagWithTS struct { + Etag string + Timestamp time.Time +}