diff --git a/service/api/service.go b/service/api/service.go index 8ab7eb26..ac2cea36 100644 --- a/service/api/service.go +++ b/service/api/service.go @@ -115,7 +115,7 @@ func (s *service) appendDocument(w http.ResponseWriter, req *http.Request) { treeId = query.Get("treeId") ) timeoutCtx, cancel := context.WithTimeout(context.Background(), time.Second*30) - err := s.documentService.UpdateDocument(timeoutCtx, treeId, text) + err := s.documentService.UpdateDocumentTree(timeoutCtx, treeId, text) cancel() if err != nil { sendText(w, http.StatusInternalServerError, err.Error()) diff --git a/service/sync/document/service.go b/service/sync/document/service.go index a20f2bd1..7d5d2b18 100644 --- a/service/sync/document/service.go +++ b/service/sync/document/service.go @@ -5,7 +5,6 @@ import ( "github.com/anytypeio/go-anytype-infrastructure-experiments/app" "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" - "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/acltree" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/testutils/testchanges/testchangepb" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/tree" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/treestorage" @@ -33,8 +32,9 @@ type service struct { } type Service interface { - UpdateDocument(ctx context.Context, id, text string) error - CreateDocument(ctx context.Context, text string) (string, error) + UpdateDocumentTree(ctx context.Context, id, text string) error + CreateACLTree(ctx context.Context) (id string, err error) + CreateDocumentTree(ctx context.Context, aclTreeId string, text string) (id string, err error) } func New() app.Component { @@ -65,7 +65,7 @@ func (s *service) Close(ctx context.Context) (err error) { return nil } -func (s *service) UpdateDocument(ctx context.Context, id, text string) (err error) { +func (s *service) UpdateDocumentTree(ctx context.Context, id, text string) (err error) { var ( ch *aclpb.RawChange header *treepb.TreeHeader @@ -75,24 +75,28 @@ func (s *service) UpdateDocument(ctx context.Context, id, text string) (err erro log.With(zap.String("id", id), zap.String("text", text)). Debug("updating document") - err = s.treeCache.Do(ctx, id, func(tree acltree.ACLTree) error { - ch, err = tree.AddContent(ctx, func(builder acltree.ChangeBuilder) error { - builder.AddChangeContent( - &testchangepb.PlainTextChangeData{ - Content: []*testchangepb.PlainTextChangeContent{ - createAppendTextChangeContent(text), - }, - }) + err = s.treeCache.Do(ctx, id, func(obj interface{}) error { + docTree := obj.(tree.DocTree) + err = s.treeCache.Do(ctx, docTree.Header().AclTreeId, func(obj interface{}) error { + aclTree := obj.(tree.ACLTree) + aclTree.RLock() + defer aclTree.RUnlock() + + content := createAppendTextChange(text) + _, err := docTree.AddContent(ctx, aclTree, content, false) + if err != nil { + return err + } return nil }) if err != nil { return err } - id = tree.ID() - heads = tree.Heads() - header = tree.Header() - snapshotPath = tree.SnapshotPath() + id = docTree.ID() + heads = docTree.Heads() + header = docTree.Header() + snapshotPath = docTree.SnapshotPath() return nil }) if err != nil { @@ -176,11 +180,12 @@ func (s *service) CreateDocumentTree(ctx context.Context, aclTreeId string, text snapshotPath []string heads []string ) - err = s.treeCache.Do(ctx, aclTreeId, func(t tree.ACLTree) error { + err = s.treeCache.Do(ctx, aclTreeId, func(obj interface{}) error { + t := obj.(tree.ACLTree) t.RLock() defer t.RUnlock() - content := createInitialChangeContent(text) + content := createInitialTextChange(text) doc, err := tree.CreateNewTreeStorage(acc, t, content, s.treeStorageProvider.CreateTreeStorage) if err != nil { return err @@ -225,7 +230,7 @@ func (s *service) CreateDocumentTree(ctx context.Context, aclTreeId string, text return id, err } -func createInitialChangeContent(text string) proto.Marshaler { +func createInitialTextChange(text string) proto.Marshaler { return &testchangepb.PlainTextChangeData{ Content: []*testchangepb.PlainTextChangeContent{ createAppendTextChangeContent(text), @@ -234,6 +239,14 @@ func createInitialChangeContent(text string) proto.Marshaler { } } +func createAppendTextChange(text string) proto.Marshaler { + return &testchangepb.PlainTextChangeData{ + Content: []*testchangepb.PlainTextChangeContent{ + createAppendTextChangeContent(text), + }, + } +} + func createAppendTextChangeContent(text string) *testchangepb.PlainTextChangeContent { return &testchangepb.PlainTextChangeContent{ Value: &testchangepb.PlainTextChangeContentValueOfTextAppend{ diff --git a/service/treecache/service.go b/service/treecache/service.go index 1176f2cb..632623ad 100644 --- a/service/treecache/service.go +++ b/service/treecache/service.go @@ -2,6 +2,7 @@ package treecache import ( "context" + "fmt" "github.com/anytypeio/go-anytype-infrastructure-experiments/app" "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclchanges/aclpb" @@ -17,14 +18,14 @@ import ( const CName = "treecache" // TODO: add context -type ACLTreeFunc = func(tree tree.ACLTree) error +type TreeFunc = func(tree interface{}) error type ChangeBuildFunc = func(builder acltree.ChangeBuilder) error var log = logger.NewNamed("treecache") type Service interface { - Do(ctx context.Context, treeId string, f ACLTreeFunc) error - Add(ctx context.Context, treeId string, header *treepb.TreeHeader, changes []*aclpb.RawChange, f ACLTreeFunc) error + Do(ctx context.Context, treeId string, f TreeFunc) error + Add(ctx context.Context, treeId string, header *treepb.TreeHeader, changes []*aclpb.RawChange, f TreeFunc) error } type service struct { @@ -37,7 +38,7 @@ func New() app.ComponentRunnable { return &service{} } -func (s *service) Do(ctx context.Context, treeId string, f ACLTreeFunc) error { +func (s *service) Do(ctx context.Context, treeId string, f TreeFunc) error { log. With(zap.String("treeId", treeId)). Debug("requesting tree from cache to perform operation") @@ -47,10 +48,10 @@ func (s *service) Do(ctx context.Context, treeId string, f ACLTreeFunc) error { if err != nil { return err } - return f(t.(tree.ACLTree)) + return f(t) } -func (s *service) Add(ctx context.Context, treeId string, header *treepb.TreeHeader, changes []*aclpb.RawChange, f ACLTreeFunc) error { +func (s *service) Add(ctx context.Context, treeId string, header *treepb.TreeHeader, changes []*aclpb.RawChange, f TreeFunc) error { log. With(zap.String("treeId", treeId), zap.Int("len(changes)", len(changes))). Debug("adding tree with changes") @@ -83,11 +84,36 @@ func (s *service) Close(ctx context.Context) (err error) { } func (s *service) loadTree(ctx context.Context, id string) (ocache.Object, error) { - tree, err := s.treeProvider.TreeStorage(id) + t, err := s.treeProvider.TreeStorage(id) if err != nil { return nil, err } - // TODO: should probably accept nil listeners - aclTree, err := acltree.BuildACLTree(tree, s.account.Account(), acltree.NoOpListener{}) - return aclTree, err + header, err := t.Header() + if err != nil { + return nil, err + } + + switch header.Type { + case treepb.TreeHeader_ACLTree: + return tree.BuildACLTreeWithIdentity(t, s.account.Account(), nil) + case treepb.TreeHeader_DocTree: + break + default: + return nil, fmt.Errorf("incorrect type") + } + var docTree tree.DocTree + // TODO: it is a question if we need to use ACLTree on the first tree build, because we can think that the tree is already validated + err = s.Do(ctx, header.AclTreeId, func(obj interface{}) error { + aclTree := obj.(tree.ACLTree) + aclTree.RLock() + defer aclTree.RUnlock() + + docTree, err = tree.BuildDocTreeWithIdentity(t, s.account.Account(), nil, aclTree) + if err != nil { + return err + } + return nil + }) + + return docTree, err }