From f213ec7efe3ac61b461ac6e4d3d4db602f02948a Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Thu, 20 Oct 2022 18:56:09 +0200 Subject: [PATCH] Fix bug with head update not being sent on first receive --- common/commonspace/space.go | 28 ++++++++++--------- .../syncservice/synchandler_test.go | 8 ------ common/commonspace/synctree/synctree.go | 16 ++++++++--- common/commonspace/synctree/synctree_test.go | 2 +- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/common/commonspace/space.go b/common/commonspace/space.go index c53ca882..3e83ee91 100644 --- a/common/commonspace/space.go +++ b/common/commonspace/space.go @@ -13,8 +13,8 @@ import ( "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list" - storage2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" - tree2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" + aclstorage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" + tree "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey" "sync" @@ -54,9 +54,9 @@ type Space interface { SpaceSyncRpc() RpcHandler - DeriveTree(ctx context.Context, payload tree2.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tree2.ObjectTree, error) - CreateTree(ctx context.Context, payload tree2.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tree2.ObjectTree, error) - BuildTree(ctx context.Context, id string, listener updatelistener.UpdateListener) (tree2.ObjectTree, error) + DeriveTree(ctx context.Context, payload tree.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tree.ObjectTree, error) + CreateTree(ctx context.Context, payload tree.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tree.ObjectTree, error) + BuildTree(ctx context.Context, id string, listener updatelistener.UpdateListener) (tree.ObjectTree, error) Close() error } @@ -120,7 +120,7 @@ func (s *space) StoredIds() []string { return s.diffService.AllIds() } -func (s *space) DeriveTree(ctx context.Context, payload tree2.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tr tree2.ObjectTree, err error) { +func (s *space) DeriveTree(ctx context.Context, payload tree.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tr tree.ObjectTree, err error) { if s.isClosed.Load() { err = ErrSpaceClosed return @@ -128,7 +128,7 @@ func (s *space) DeriveTree(ctx context.Context, payload tree2.ObjectTreeCreatePa return synctree.DeriveSyncTree(ctx, payload, s.syncService.SyncClient(), listener, s.aclList, s.storage.CreateTreeStorage) } -func (s *space) CreateTree(ctx context.Context, payload tree2.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tr tree2.ObjectTree, err error) { +func (s *space) CreateTree(ctx context.Context, payload tree.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tr tree.ObjectTree, err error) { if s.isClosed.Load() { err = ErrSpaceClosed return @@ -136,7 +136,7 @@ func (s *space) CreateTree(ctx context.Context, payload tree2.ObjectTreeCreatePa return synctree.CreateSyncTree(ctx, payload, s.syncService.SyncClient(), listener, s.aclList, s.storage.CreateTreeStorage) } -func (s *space) BuildTree(ctx context.Context, id string, listener updatelistener.UpdateListener) (t tree2.ObjectTree, err error) { +func (s *space) BuildTree(ctx context.Context, id string, listener updatelistener.UpdateListener) (t tree.ObjectTree, err error) { if s.isClosed.Load() { err = ErrSpaceClosed return @@ -154,11 +154,13 @@ func (s *space) BuildTree(ctx context.Context, id string, listener updatelistene } store, err := s.storage.TreeStorage(id) - if err != nil && err != storage2.ErrUnknownTreeId { + if err != nil && err != aclstorage.ErrUnknownTreeId { return } - if err == storage2.ErrUnknownTreeId { + isFirstBuild := false + if err == aclstorage.ErrUnknownTreeId { + isFirstBuild = true var resp *spacesyncproto.ObjectSyncMessage resp, err = getTreeRemote() if err != nil { @@ -166,7 +168,7 @@ func (s *space) BuildTree(ctx context.Context, id string, listener updatelistene } fullSyncResp := resp.GetContent().GetFullSyncResponse() - payload := storage2.TreeStorageCreatePayload{ + payload := aclstorage.TreeStorageCreatePayload{ TreeId: resp.TreeId, RootRawChange: resp.RootChange, Changes: fullSyncResp.Changes, @@ -174,7 +176,7 @@ func (s *space) BuildTree(ctx context.Context, id string, listener updatelistene } // basically building tree with inmemory storage and validating that it was without errors - err = tree2.ValidateRawTree(payload, s.aclList) + err = tree.ValidateRawTree(payload, s.aclList) if err != nil { return } @@ -184,7 +186,7 @@ func (s *space) BuildTree(ctx context.Context, id string, listener updatelistene return } } - return synctree.BuildSyncTree(ctx, s.syncService.SyncClient(), store.(storage2.TreeStorage), listener, s.aclList) + return synctree.BuildSyncTree(ctx, s.syncService.SyncClient(), store.(aclstorage.TreeStorage), listener, s.aclList, isFirstBuild) } func (s *space) Close() error { diff --git a/common/commonspace/syncservice/synchandler_test.go b/common/commonspace/syncservice/synchandler_test.go index a0f2fdd9..1b18be9f 100644 --- a/common/commonspace/syncservice/synchandler_test.go +++ b/common/commonspace/syncservice/synchandler_test.go @@ -15,14 +15,6 @@ import ( "testing" ) -type treeContainer struct { - objTree tree.ObjectTree -} - -func (t treeContainer) Tree() tree.ObjectTree { - return t.objTree -} - type testObjTreeMock struct { *mock_tree.MockObjectTree m sync.Mutex diff --git a/common/commonspace/synctree/synctree.go b/common/commonspace/synctree/synctree.go index 4cd6e2ee..4c83cf95 100644 --- a/common/commonspace/synctree/synctree.go +++ b/common/commonspace/synctree/synctree.go @@ -77,8 +77,9 @@ func BuildSyncTree( syncClient syncservice.SyncClient, treeStorage storage.TreeStorage, listener updatelistener.UpdateListener, - aclList list.ACLList) (t tree2.ObjectTree, err error) { - return buildSyncTree(ctx, syncClient, treeStorage, listener, aclList) + aclList list.ACLList, + isFirstBuild bool) (t tree2.ObjectTree, err error) { + return buildSyncTree(ctx, syncClient, treeStorage, listener, aclList, isFirstBuild) } func buildSyncTree( @@ -86,7 +87,8 @@ func buildSyncTree( syncClient syncservice.SyncClient, treeStorage storage.TreeStorage, listener updatelistener.UpdateListener, - aclList list.ACLList) (t tree2.ObjectTree, err error) { + aclList list.ACLList, + isFirstBuild bool) (t tree2.ObjectTree, err error) { t, err = buildObjectTree(treeStorage, aclList) if err != nil { return @@ -99,7 +101,13 @@ func buildSyncTree( headUpdate := syncClient.CreateHeadUpdate(t, nil) // here we will have different behaviour based on who is sending this update - err = syncClient.BroadcastAsyncOrSendResponsible(headUpdate) + if isFirstBuild { + // send to everybody, because everybody should know that the node or client got new tree + err = syncClient.BroadcastAsync(headUpdate) + } else { + // send either to everybody if client or to replica set if node + err = syncClient.BroadcastAsyncOrSendResponsible(headUpdate) + } return } diff --git a/common/commonspace/synctree/synctree_test.go b/common/commonspace/synctree/synctree_test.go index 04ec069d..4f9d2ac4 100644 --- a/common/commonspace/synctree/synctree_test.go +++ b/common/commonspace/synctree/synctree_test.go @@ -104,7 +104,7 @@ func Test_BuildSyncTree(t *testing.T) { syncClientMock.EXPECT().CreateHeadUpdate(syncTreeMatcher{objTreeMock, syncClientMock, updateListenerMock}, gomock.Nil()).Return(headUpdate) syncClientMock.EXPECT().BroadcastAsyncOrSendResponsible(gomock.Eq(headUpdate)).Return(nil) - tr, err := BuildSyncTree(ctx, syncClientMock, storageMock, updateListenerMock, aclListMock) + tr, err := BuildSyncTree(ctx, syncClientMock, storageMock, updateListenerMock, aclListMock, false) require.NoError(t, err) t.Run("AddRawChanges update", func(t *testing.T) {