From ca638ddc516bc3c465114ca8ac9a5fe33d93f3e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Fri, 28 Apr 2023 13:50:59 +0200 Subject: [PATCH] cache special drive items until space root changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- .../pkg/config/defaults/defaultconfig.go | 2 + services/graph/pkg/service/v0/driveitems.go | 37 ++++++++++++++++++- services/graph/pkg/service/v0/drives.go | 2 +- services/graph/pkg/service/v0/graph.go | 2 +- services/graph/pkg/service/v0/service.go | 2 +- 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/services/graph/pkg/config/defaults/defaultconfig.go b/services/graph/pkg/config/defaults/defaultconfig.go index eff3b8477..42545f19a 100644 --- a/services/graph/pkg/config/defaults/defaultconfig.go +++ b/services/graph/pkg/config/defaults/defaultconfig.go @@ -54,6 +54,8 @@ func DefaultConfig() *config.Config { WebDavPath: "/dav/spaces/", DefaultQuota: "1000000000", // 30 minutes + ExtendedSpacePropertiesCacheTTL: 1800, + // 30 minutes GroupsCacheTTL: 1800, // 30 minutes UsersCacheTTL: 1800, diff --git a/services/graph/pkg/service/v0/driveitems.go b/services/graph/pkg/service/v0/driveitems.go index 58b87cf38..86fb03a31 100644 --- a/services/graph/pkg/service/v0/driveitems.go +++ b/services/graph/pkg/service/v0/driveitems.go @@ -215,8 +215,20 @@ func (g Graph) getPathForResource(ctx context.Context, id storageprovider.Resour return res.Path, err } -// getExtendedSpaceProperties reads properties from the opaque and transforms them into driveItems -func (g Graph) getExtendedSpaceProperties(ctx context.Context, baseURL *url.URL, space *storageprovider.StorageSpace) []libregraph.DriveItem { +// getSpecialDriveItems reads properties from the opaque and transforms them into driveItems +func (g Graph) getSpecialDriveItems(ctx context.Context, baseURL *url.URL, space *storageprovider.StorageSpace) []libregraph.DriveItem { + + // if the root is older or equal to our cache we can reuse the cached extended spaces properties + if entry := g.specialDriveItemsCache.Get(spaceRootStatKey(space.Root)); entry != nil { + if spe, ok := entry.Value().(specialDriveItemEntry); ok { + if spe.rootMtime != nil && space.Mtime != nil { + if spe.rootMtime.Seconds >= space.Mtime.Seconds { // second precision is good enough + return spe.specialDriveItems + } + } + } + } + var spaceItems []libregraph.DriveItem if space.Opaque == nil { return nil @@ -235,9 +247,30 @@ func (g Graph) getExtendedSpaceProperties(ctx context.Context, baseURL *url.URL, } } } + + // cache properties + spacePropertiesEntry := specialDriveItemEntry{ + specialDriveItems: spaceItems, + rootMtime: space.Mtime, + } + g.specialDriveItemsCache.Set(spaceRootStatKey(space.Root), spacePropertiesEntry, time.Duration(g.config.Spaces.ExtendedSpacePropertiesCacheTTL)) + return spaceItems } +// generates a space root stat cache key used to detect changes in a space +func spaceRootStatKey(id *storageprovider.ResourceId) string { + if id == nil { + return "" + } + return id.StorageId + "$" + id.SpaceId + "!" + id.OpaqueId +} + +type specialDriveItemEntry struct { + specialDriveItems []libregraph.DriveItem + rootMtime *types.Timestamp +} + func (g Graph) getSpecialDriveItem(ctx context.Context, id storageprovider.ResourceId, itemName string, baseURL *url.URL, space *storageprovider.StorageSpace) *libregraph.DriveItem { var spaceItem *libregraph.DriveItem if id.SpaceId == "" && id.OpaqueId == "" { diff --git a/services/graph/pkg/service/v0/drives.go b/services/graph/pkg/service/v0/drives.go index 50d821546..f3df77b44 100644 --- a/services/graph/pkg/service/v0/drives.go +++ b/services/graph/pkg/service/v0/drives.go @@ -536,7 +536,7 @@ func (g Graph) formatDrives(ctx context.Context, baseURL *url.URL, storageSpaces // can't access disabled space if utils.ReadPlainFromOpaque(storageSpace.Opaque, "trashed") != "trashed" { - res.Special = g.getExtendedSpaceProperties(ctx, baseURL, storageSpace) + res.Special = g.getSpecialDriveItems(ctx, baseURL, storageSpace) quota, err := g.getDriveQuota(ctx, storageSpace) res.Quota = "a if err != nil { diff --git a/services/graph/pkg/service/v0/graph.go b/services/graph/pkg/service/v0/graph.go index 4ab673ddc..eab4903d4 100644 --- a/services/graph/pkg/service/v0/graph.go +++ b/services/graph/pkg/service/v0/graph.go @@ -65,7 +65,7 @@ type Graph struct { gatewayClient gateway.GatewayAPIClient roleService RoleService permissionsService Permissions - spacePropertiesCache *ttlcache.Cache[string, interface{}] + specialDriveItemsCache *ttlcache.Cache[string, interface{}] usersCache *ttlcache.Cache[string, libregraph.User] groupsCache *ttlcache.Cache[string, libregraph.Group] eventsPublisher events.Publisher diff --git a/services/graph/pkg/service/v0/service.go b/services/graph/pkg/service/v0/service.go index 8984685d3..234e182fb 100644 --- a/services/graph/pkg/service/v0/service.go +++ b/services/graph/pkg/service/v0/service.go @@ -136,7 +136,7 @@ func NewService(opts ...Option) (Graph, error) { config: options.Config, mux: m, logger: &options.Logger, - spacePropertiesCache: spacePropertiesCache, + specialDriveItemsCache: spacePropertiesCache, usersCache: usersCache, groupsCache: groupsCache, eventsPublisher: options.EventsPublisher,