diff --git a/pkg/acl/acltree/acltree.go b/pkg/acl/acltree/acltree.go index 9761e545..90bf337a 100644 --- a/pkg/acl/acltree/acltree.go +++ b/pkg/acl/acltree/acltree.go @@ -38,6 +38,7 @@ type ACLTree interface { ACLState() *ACLState AddContent(ctx context.Context, f func(builder ChangeBuilder) error) (*Change, error) AddChanges(ctx context.Context, changes ...*Change) (AddResult, error) + AddRawChanges(ctx context.Context, changes ...*aclpb.RawChange) (AddResult, error) Heads() []string Root() *Change Iterate(func(change *Change) bool) @@ -245,6 +246,20 @@ func (a *aclTree) AddContent(ctx context.Context, build func(builder ChangeBuild return ch, nil } +func (a *aclTree) AddRawChanges(ctx context.Context, rawChanges ...*aclpb.RawChange) (AddResult, error) { + var aclChanges []*Change + for _, ch := range rawChanges { + change, err := NewFromRawChange(ch) + // TODO: think what if we will have incorrect signatures on rawChanges, how everything will work + if err != nil { + continue + } + aclChanges = append(aclChanges, change) + } + + return a.AddChanges(ctx, aclChanges...) +} + func (a *aclTree) AddChanges(ctx context.Context, changes ...*Change) (AddResult, error) { a.Lock() // TODO: make proper error handling, because there are a lot of corner cases where this will break diff --git a/service/sync/requesthandler.go b/service/sync/requesthandler.go new file mode 100644 index 00000000..c935885a --- /dev/null +++ b/service/sync/requesthandler.go @@ -0,0 +1,43 @@ +package sync + +import ( + "context" + "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/acltree" + "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" +) + +type requestHander struct { + treeCache treecache.Service + client SyncClient +} + +func (r *requestHander) HandleHeadUpdate(ctx context.Context, senderId string, update *syncpb.SyncHeadUpdate) error { + err := r.treeCache.Do(ctx, update.TreeId, func(tree acltree.ACLTree) error { + _, err := tree.AddRawChanges(ctx, update.Changes...) + if err != nil { + return err + } + shouldFullSync := !r.compareHeads(update.Heads, tree.Heads()) + + return nil + }) + if err != nil { + return err + } + return nil +} + +func (r *requestHander) compareHeads(syncHeads []*syncpb.SyncHead, heads []string) bool { + for _, head := range syncHeads { + if slice.FindPos(heads, head.Id) == -1 { + return false + } + } + return true +} + +func (r *requestHander) prepareFullSyncRequest(tree acltree.ACLTree) (*syncpb.SyncFullRequest, error) { + +} diff --git a/service/sync/syncclient.go b/service/sync/syncclient.go new file mode 100644 index 00000000..95354982 --- /dev/null +++ b/service/sync/syncclient.go @@ -0,0 +1,8 @@ +package sync + +import "github.com/anytypeio/go-anytype-infrastructure-experiments/service/sync/syncpb" + +type SyncClient interface { + NotifyHeadsChanged(update *syncpb.SyncHeadUpdate) error + RequestFullSync(id string, request *syncpb.SyncFullRequest) error +}