diff --git a/pkg/acl/treestorage/inmemory.go b/pkg/acl/treestorage/inmemory.go index 3120d27a..8a2b7865 100644 --- a/pkg/acl/treestorage/inmemory.go +++ b/pkg/acl/treestorage/inmemory.go @@ -134,3 +134,34 @@ func (t *inMemoryTreeStorage) GetChange(ctx context.Context, changeId string) (* } return nil, fmt.Errorf("could not get change with id: %s", changeId) } + +type inMemoryTreeStorageProvider struct { + trees map[string]TreeStorage +} + +func (i *inMemoryTreeStorageProvider) TreeStorage(treeId string) (TreeStorage, error) { + if tree, exists := i.trees[treeId]; exists { + return tree, nil + } + return nil, UnknownTreeId +} + +func (i *inMemoryTreeStorageProvider) InsertTree(tree TreeStorage) error { + if tree == nil { + return fmt.Errorf("tree should not be nil") + } + + id, err := tree.TreeID() + if err != nil { + return err + } + + i.trees[id] = tree + return nil +} + +func NewInMemoryTreeStorageProvider() Provider { + return &inMemoryTreeStorageProvider{ + trees: make(map[string]TreeStorage), + } +} diff --git a/pkg/acl/treestorage/provider.go b/pkg/acl/treestorage/provider.go index bf0c074c..c62096db 100644 --- a/pkg/acl/treestorage/provider.go +++ b/pkg/acl/treestorage/provider.go @@ -1,39 +1,10 @@ package treestorage -import "fmt" +import "errors" + +var UnknownTreeId = errors.New("tree does not exist") type Provider interface { TreeStorage(treeId string) (TreeStorage, error) InsertTree(tree TreeStorage) error } - -type inMemoryTreeStorageProvider struct { - trees map[string]TreeStorage -} - -func (i *inMemoryTreeStorageProvider) TreeStorage(treeId string) (TreeStorage, error) { - if tree, exists := i.trees[treeId]; exists { - return tree, nil - } - return nil, fmt.Errorf("tree with id %s doesn't exist", treeId) -} - -func (i *inMemoryTreeStorageProvider) InsertTree(tree TreeStorage) error { - if tree == nil { - return fmt.Errorf("tree should not be nil") - } - - id, err := tree.TreeID() - if err != nil { - return err - } - - i.trees[id] = tree - return nil -} - -func NewInMemoryTreeStorageProvider() Provider { - return &inMemoryTreeStorageProvider{ - trees: make(map[string]TreeStorage), - } -} diff --git a/service/sync/requesthandler.go b/service/sync/requesthandler.go index 65f2972d..b4d0758b 100644 --- a/service/sync/requesthandler.go +++ b/service/sync/requesthandler.go @@ -3,6 +3,7 @@ package sync import ( "context" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/acltree" + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage" "github.com/anytypeio/go-anytype-infrastructure-experiments/service/sync/syncpb" "github.com/anytypeio/go-anytype-infrastructure-experiments/service/treecache" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/slice" @@ -14,21 +15,12 @@ type requestHander struct { } func (r *requestHander) HandleHeadUpdate(ctx context.Context, senderId string, update *syncpb.SyncHeadUpdate) (err error) { - var fullRequest *syncpb.SyncFullRequest - var snapshotPath []string - var result acltree.AddResult - defer func() { - if err != nil || fullRequest != nil { - return - } - newUpdate := &syncpb.SyncHeadUpdate{ - Heads: result.Heads, - Changes: result.Added, - SnapshotPath: snapshotPath, - TreeId: update.TreeId, - } - err = r.client.NotifyHeadsChanged(newUpdate) - }() + var ( + fullRequest *syncpb.SyncFullRequest + snapshotPath []string + result acltree.AddResult + ) + err = r.treeCache.Do(ctx, update.TreeId, func(tree acltree.ACLTree) error { // TODO: check if we already have those changes result, err = tree.AddRawChanges(ctx, update.Changes...) @@ -45,16 +37,33 @@ func (r *requestHander) HandleHeadUpdate(ctx context.Context, senderId string, u } return nil }) - if err != nil { - return err + // if there are no such tree + if err == treestorage.UnknownTreeId { + fullRequest = &syncpb.SyncFullRequest{ + TreeId: update.TreeId, + } } + // if we have incompatible heads, or we haven't seen the tree at all if fullRequest != nil { return r.client.RequestFullSync(senderId, fullRequest) } + // if error or nothing has changed + if err != nil || len(result.Added) == 0 { + return err + } + // otherwise sending heads update message + newUpdate := &syncpb.SyncHeadUpdate{ + Heads: result.Heads, + Changes: result.Added, + SnapshotPath: snapshotPath, + TreeId: update.TreeId, + } + err = r.client.NotifyHeadsChanged(newUpdate) return } func (r *requestHander) HandleFullSync(ctx context.Context, senderId string, request *syncpb.SyncFullRequest) error { + // TODO: add case of new tree return nil }