From 9dc366d42070eb19304faa8324903f234ac024d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Mon, 22 Aug 2022 10:59:37 +0000 Subject: [PATCH] use new mtime for if-unmodified-since MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- pkg/share/manager/jsoncs3/jsoncs3.go | 84 +++++++++++++++++-- .../jsoncs3/providercache/providercache.go | 21 +---- .../receivedsharecache/receivedsharecache.go | 20 +---- .../manager/jsoncs3/sharecache/sharecache.go | 20 +---- 4 files changed, 84 insertions(+), 61 deletions(-) diff --git a/pkg/share/manager/jsoncs3/jsoncs3.go b/pkg/share/manager/jsoncs3/jsoncs3.go index 6b7aea6b30..821b7baf7b 100644 --- a/pkg/share/manager/jsoncs3/jsoncs3.go +++ b/pkg/share/manager/jsoncs3/jsoncs3.go @@ -228,13 +228,26 @@ func (m *Manager) Share(ctx context.Context, md *provider.ResourceInfo, g *colla } err = m.Cache.Add(ctx, md.Id.StorageId, md.Id.SpaceId, shareID, s) + if _, ok := err.(errtypes.IsPreconditionFailed); ok { + if err := m.Cache.Sync(ctx, md.Id.StorageId, md.Id.SpaceId); err != nil { + return nil, err + } + err = m.Cache.Add(ctx, md.Id.StorageId, md.Id.SpaceId, shareID, s) + // TODO try more often? + } if err != nil { return nil, err } err = m.CreatedCache.Add(ctx, s.GetCreator().GetOpaqueId(), shareID) + if _, ok := err.(errtypes.IsPreconditionFailed); ok { + if err := m.CreatedCache.Sync(ctx, s.GetCreator().GetOpaqueId()); err != nil { + return nil, err + } + err = m.CreatedCache.Add(ctx, s.GetCreator().GetOpaqueId(), shareID) + // TODO try more often? + } if err != nil { - // TODO when persisting fails, download, readd and persist again return nil, err } @@ -248,12 +261,28 @@ func (m *Manager) Share(ctx context.Context, md *provider.ResourceInfo, g *colla Share: s, State: collaboration.ShareState_SHARE_STATE_PENDING, } - m.UserReceivedStates.Add(ctx, userid, spaceID, rs) - // TODO check error - // TODO when persisting fails, download, readd and persist again + err = m.UserReceivedStates.Add(ctx, userid, spaceID, rs) + if _, ok := err.(errtypes.IsPreconditionFailed); ok { + if err := m.UserReceivedStates.Sync(ctx, s.GetCreator().GetOpaqueId()); err != nil { + return nil, err + } + err = m.UserReceivedStates.Add(ctx, userid, spaceID, rs) + // TODO try more often? + } + if err != nil { + return nil, err + } case provider.GranteeType_GRANTEE_TYPE_GROUP: groupid := g.Grantee.GetGroupId().GetOpaqueId() - if err := m.GroupReceivedCache.Add(ctx, groupid, shareID); err != nil { + err := m.GroupReceivedCache.Add(ctx, groupid, shareID) + if _, ok := err.(errtypes.IsPreconditionFailed); ok { + if err := m.GroupReceivedCache.Sync(ctx, groupid); err != nil { + return nil, err + } + err = m.GroupReceivedCache.Add(ctx, groupid, shareID) + // TODO try more often? + } + if err != nil { return nil, err } } @@ -350,12 +379,26 @@ func (m *Manager) Unshare(ctx context.Context, ref *collaboration.ShareReference storageID, spaceID, _ := shareid.Decode(s.Id.OpaqueId) err = m.Cache.Remove(ctx, storageID, spaceID, s.Id.OpaqueId) + if _, ok := err.(errtypes.IsPreconditionFailed); ok { + if err := m.Cache.Sync(ctx, storageID, spaceID); err != nil { + return err + } + err = m.Cache.Remove(ctx, storageID, spaceID, s.Id.OpaqueId) + // TODO try more often? + } if err != nil { return err } // remove from created cache err = m.CreatedCache.Remove(ctx, s.GetCreator().GetOpaqueId(), s.Id.OpaqueId) + if _, ok := err.(errtypes.IsPreconditionFailed); ok { + if err := m.CreatedCache.Sync(ctx, s.GetCreator().GetOpaqueId()); err != nil { + return err + } + err = m.CreatedCache.Remove(ctx, s.GetCreator().GetOpaqueId(), s.Id.OpaqueId) + // TODO try more often? + } if err != nil { return err } @@ -387,8 +430,24 @@ func (m *Manager) UpdateShare(ctx context.Context, ref *collaboration.ShareRefer s.Mtime = utils.TSNow() // Update provider cache - m.Cache.Persist(ctx, s.ResourceId.StorageId, s.ResourceId.SpaceId) - // TODO when persisting fails, download, readd and persist again + err = m.Cache.Persist(ctx, s.ResourceId.StorageId, s.ResourceId.SpaceId) + // when persisting fails + if _, ok := err.(errtypes.IsPreconditionFailed); ok { + // reupdate + s, err := m.get(ctx, ref) // does an implicit sync + if err != nil { + return nil, err + } + s.Permissions = p + s.Mtime = utils.TSNow() + + // persist again + err = m.Cache.Persist(ctx, s.ResourceId.StorageId, s.ResourceId.SpaceId) + // TODO try more often? + } + if err != nil { + return nil, err + } return s, nil } @@ -618,8 +677,15 @@ func (m *Manager) UpdateReceivedShare(ctx context.Context, receivedShare *collab userID := ctxpkg.ContextMustGetUser(ctx) - m.UserReceivedStates.Add(ctx, userID.GetId().GetOpaqueId(), rs.Share.ResourceId.StorageId+"^"+rs.Share.ResourceId.SpaceId, rs) - // TODO when persisting fails, download, readd and persist again + err = m.UserReceivedStates.Add(ctx, userID.GetId().GetOpaqueId(), rs.Share.ResourceId.StorageId+"^"+rs.Share.ResourceId.SpaceId, rs) + if _, ok := err.(errtypes.IsPreconditionFailed); ok { + // when persisting fails, download, readd and persist again + if err := m.UserReceivedStates.Sync(ctx, userID.GetId().GetOpaqueId()); err != nil { + return nil, err + } + err = m.UserReceivedStates.Add(ctx, userID.GetId().GetOpaqueId(), rs.Share.ResourceId.StorageId+"^"+rs.Share.ResourceId.SpaceId, rs) + // TODO try more often? + } return rs, nil } diff --git a/pkg/share/manager/jsoncs3/providercache/providercache.go b/pkg/share/manager/jsoncs3/providercache/providercache.go index bd6d3f71cc..13879271e9 100644 --- a/pkg/share/manager/jsoncs3/providercache/providercache.go +++ b/pkg/share/manager/jsoncs3/providercache/providercache.go @@ -141,8 +141,6 @@ func (c *Cache) Persist(ctx context.Context, storageID, spaceID string) error { return nil } - oldMtime := c.Providers[storageID].Spaces[spaceID].Mtime - c.Providers[storageID].Spaces[spaceID].Mtime = time.Now() createdBytes, err := json.Marshal(c.Providers[storageID].Spaces[spaceID]) if err != nil { @@ -153,24 +151,11 @@ func (c *Cache) Persist(ctx context.Context, storageID, spaceID string) error { return err } - if err := c.storage.Upload(ctx, metadata.UploadRequest{ + return c.storage.Upload(ctx, metadata.UploadRequest{ Path: jsonPath, Content: createdBytes, - IfUnmodifiedSince: oldMtime, - }); err != nil { - return err - } - - /* - FIXME stating here introduces a lost read because the file might have been overwritten written between the above upload and this stat - the local cache is updated with Sync during reads - info, err := c.storage.Stat(ctx, jsonPath) - if err != nil { - return err - } - c.Providers[storageID].Spaces[spaceID].Mtime = utils.TSToTime(info.Mtime) - */ - return nil + IfUnmodifiedSince: c.Providers[storageID].Spaces[spaceID].Mtime, + }) } // Sync updates the in-memory data with the data from the storage if it is outdated diff --git a/pkg/share/manager/jsoncs3/receivedsharecache/receivedsharecache.go b/pkg/share/manager/jsoncs3/receivedsharecache/receivedsharecache.go index 4b2d8a756d..8eac0df917 100644 --- a/pkg/share/manager/jsoncs3/receivedsharecache/receivedsharecache.go +++ b/pkg/share/manager/jsoncs3/receivedsharecache/receivedsharecache.go @@ -148,7 +148,6 @@ func (c *Cache) Persist(ctx context.Context, userID string) error { return nil } - oldMtime := c.ReceivedSpaces[userID].Mtime c.ReceivedSpaces[userID].Mtime = time.Now() createdBytes, err := json.Marshal(c.ReceivedSpaces[userID]) if err != nil { @@ -159,24 +158,11 @@ func (c *Cache) Persist(ctx context.Context, userID string) error { return err } - if err := c.storage.Upload(ctx, metadata.UploadRequest{ + return c.storage.Upload(ctx, metadata.UploadRequest{ Path: jsonPath, Content: createdBytes, - IfUnmodifiedSince: oldMtime, - }); err != nil { - return err - } - - /* - FIXME stating here introduces a lost read because the file might have been overwritten written between the above upload and this stat - the local cache is updated with Sync during reads - info, err := c.storage.Stat(ctx, jsonPath) - if err != nil { - return err - } - c.ReceivedSpaces[userID].Mtime = utils.TSToTime(info.Mtime) - */ - return nil + IfUnmodifiedSince: c.ReceivedSpaces[userID].Mtime, + }) } func userJSONPath(userID string) string { diff --git a/pkg/share/manager/jsoncs3/sharecache/sharecache.go b/pkg/share/manager/jsoncs3/sharecache/sharecache.go index 7683b217da..40470d3d90 100644 --- a/pkg/share/manager/jsoncs3/sharecache/sharecache.go +++ b/pkg/share/manager/jsoncs3/sharecache/sharecache.go @@ -168,7 +168,6 @@ func (c *Cache) Sync(ctx context.Context, userID string) error { // Persist persists the data for one user/group to the storage func (c *Cache) Persist(ctx context.Context, userid string) error { - oldMtime := c.UserShares[userid].Mtime c.UserShares[userid].Mtime = time.Now() createdBytes, err := json.Marshal(c.UserShares[userid]) @@ -180,24 +179,11 @@ func (c *Cache) Persist(ctx context.Context, userid string) error { return err } - if err := c.storage.Upload(ctx, metadata.UploadRequest{ + return c.storage.Upload(ctx, metadata.UploadRequest{ Path: jsonPath, Content: createdBytes, - IfUnmodifiedSince: oldMtime, - }); err != nil { - return err - } - - /* - FIXME stating here introduces a lost read because the file might have been overwritten written between the above upload and this stat - the local cache is updated with Sync during reads - info, err := c.storage.Stat(ctx, jsonPath) - if err != nil { - return err - } - c.UserShares[userid].Mtime = utils.TSToTime(info.Mtime) - */ - return nil + IfUnmodifiedSince: c.UserShares[userid].Mtime, + }) } func (c *Cache) userCreatedPath(userid string) string {