mirror of
https://github.com/anyproto/any-sync.git
synced 2025-06-11 02:13:49 +09:00
86 lines
2.6 KiB
Go
86 lines
2.6 KiB
Go
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"
|
|
)
|
|
|
|
type requestHander struct {
|
|
treeCache treecache.Service
|
|
client SyncClient
|
|
}
|
|
|
|
func (r *requestHander) HandleHeadUpdate(ctx context.Context, senderId string, update *syncpb.SyncHeadUpdate) (err error) {
|
|
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...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
shouldFullSync := !slice.UnsortedEquals(update.Heads, tree.Heads())
|
|
snapshotPath = tree.SnapshotPath()
|
|
if shouldFullSync {
|
|
fullRequest, err = r.prepareFullSyncRequest(update.TreeId, update.SnapshotPath, tree)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
// if there are no such tree
|
|
if err == treestorage.ErrUnknownTreeId {
|
|
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) HandleFullSyncRequest(ctx context.Context, senderId string, request *syncpb.SyncFullRequest) error {
|
|
// TODO: add case of new tree
|
|
return nil
|
|
}
|
|
|
|
func (r *requestHander) HandleFullSyncResponse(ctx context.Context, senderId string, request *syncpb.SyncFullRequest) error {
|
|
// TODO: add case of new tree
|
|
return nil
|
|
}
|
|
|
|
func (r *requestHander) prepareFullSyncRequest(treeId string, theirPath []string, tree acltree.ACLTree) (*syncpb.SyncFullRequest, error) {
|
|
ourChanges, err := tree.ChangesAfterCommonSnapshot(theirPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &syncpb.SyncFullRequest{
|
|
Heads: tree.Heads(),
|
|
Changes: ourChanges,
|
|
TreeId: treeId,
|
|
SnapshotPath: tree.SnapshotPath(),
|
|
}, nil
|
|
}
|