WIP more deletion checks

This commit is contained in:
mcrakhman 2022-11-12 17:49:25 +01:00 committed by Mikhail Iudin
parent 676976e7d3
commit a5fe46e50e
No known key found for this signature in database
GPG Key ID: FAAAA8BAABDFF1C0
6 changed files with 63 additions and 22 deletions

View File

@ -23,6 +23,8 @@ type Controller interface {
// CreateDocument creates new document in space
CreateDocument(spaceId string) (id string, err error)
// DeleteDocument deletes a document from space
DeleteDocument(spaceId, documentId string) (err error)
// AllDocumentIds gets all ids of documents in space
AllDocumentIds(spaceId string) (ids []string, err error)
// AddText adds text to space document
@ -97,6 +99,10 @@ func (c *controller) CreateDocument(spaceId string) (id string, err error) {
return c.docService.CreateDocument(spaceId)
}
func (c *controller) DeleteDocument(spaceId, documentId string) (err error) {
return c.docService.DeleteDocument(spaceId, documentId)
}
func (c *controller) AllDocumentIds(spaceId string) (ids []string, err error) {
return c.docService.AllDocumentIds(spaceId)
}

View File

@ -53,10 +53,18 @@ func (s *service) CreateDocument(spaceId string) (id string, err error) {
if err != nil {
return
}
id = doc.Tree().ID()
id = doc.ID()
return
}
func (s *service) DeleteDocument(spaceId, documentId string) (err error) {
space, err := s.spaceService.GetSpace(context.Background(), spaceId)
if err != nil {
return
}
return space.DeleteTree(context.Background(), documentId)
}
func (s *service) AllDocumentIds(spaceId string) (ids []string, err error) {
space, err := s.spaceService.GetSpace(context.Background(), spaceId)
if err != nil {
@ -79,5 +87,5 @@ func (s *service) DumpDocumentTree(spaceId, documentId string) (dump string, err
if err != nil {
return
}
return doc.Tree().DebugDump()
return doc.DebugDump()
}

View File

@ -69,10 +69,7 @@ func (d *diffService) HandleRangeRequest(ctx context.Context, req *spacesyncprot
}
func (d *diffService) UpdateHeads(id string, heads []string) {
d.diff.Set(ldiff.Element{
Id: id,
Head: concatStrings(heads),
})
d.syncer.UpdateHeads(id, heads)
}
func (d *diffService) AllIds() []string {
@ -80,9 +77,6 @@ func (d *diffService) AllIds() []string {
}
func (d *diffService) RemoveObjects(ids []string) {
for _, id := range ids {
d.diff.RemoveId(id)
}
d.syncer.RemoveObjects(ids)
}

View File

@ -18,6 +18,7 @@ import (
type DiffSyncer interface {
Sync(ctx context.Context) error
RemoveObjects(ids []string)
UpdateHeads(id string, heads []string)
}
func newDiffSyncer(
@ -56,10 +57,23 @@ func (d *diffSyncer) RemoveObjects(ids []string) {
d.Lock()
defer d.Unlock()
for _, id := range ids {
d.diff.RemoveId(id)
d.removedIds[id] = struct{}{}
}
}
func (d *diffSyncer) UpdateHeads(id string, heads []string) {
d.Lock()
defer d.Unlock()
if _, exists := d.removedIds[id]; exists {
return
}
d.diff.Set(ldiff.Element{
Id: id,
Head: concatStrings(heads),
})
}
func (d *diffSyncer) Sync(ctx context.Context) error {
st := time.Now()
// diffing with responsible peers according to configuration

View File

@ -8,6 +8,7 @@ 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/tree"
"sync"
)
type DeletionState int
@ -19,7 +20,7 @@ const (
type SettingsDocument interface {
tree.ObjectTree
Init()
Refresh()
DeleteObject(id string) (err error)
}
@ -45,6 +46,7 @@ type settingsDocument struct {
lastChangeId string
prov deletedIdsProvider
removeNotifyFunc RemoveObjectsFunc
deletionStateLock sync.Mutex
}
func NewSettingsDocument(ctx context.Context, deps Deps, spaceId string) (doc SettingsDocument, err error) {
@ -68,6 +70,14 @@ func NewSettingsDocument(ctx context.Context, deps Deps, spaceId string) (doc Se
return
}
func (s *settingsDocument) NotifyHeadsUpdate(id string) {
s.deletionStateLock.Lock()
if _, exists := s.deletionState[id]; exists {
s.deletionState[id] = DeletionStateQueued
}
s.deletionStateLock.Unlock()
}
func (s *settingsDocument) Update(tr tree.ObjectTree) {
ids, lastId, err := s.prov.ProvideIds(tr, s.lastChangeId)
if err != nil {
@ -86,7 +96,7 @@ func (s *settingsDocument) Rebuild(tr tree.ObjectTree) {
s.toBeDeleted(ids)
}
func (s *settingsDocument) Init() {
func (s *settingsDocument) Refresh() {
s.Lock()
defer s.Unlock()
s.Rebuild(s)
@ -94,26 +104,37 @@ func (s *settingsDocument) Init() {
func (s *settingsDocument) toBeDeleted(ids []string) {
for _, id := range ids {
s.deletionStateLock.Lock()
if state, exists := s.deletionState[id]; exists && state == DeletionStateDeleted {
s.deletionStateLock.Unlock()
continue
}
// if not already deleted
// TODO: here we can possibly have problems if the document is synced later, maybe we should block syncing with deleted documents
if _, err := s.store.TreeStorage(id); err == nil {
s.deletionState[id] = DeletionStateQueued
s.deletionStateLock.Unlock()
// doing this without lock
err := s.treeGetter.DeleteTree(context.Background(), s.spaceId, id)
if err != nil {
// TODO: some errors may tell us that the tree is actually deleted, so we should have more checks here
// TODO: add logging
continue
}
// TODO: add loop to double check that everything that should be deleted is actually deleted
s.deletionStateLock.Lock()
}
s.deletionState[id] = DeletionStateDeleted
s.deletionStateLock.Unlock()
}
// notifying about removal
s.removeNotifyFunc(ids)
}
func (s *settingsDocument) DeleteObject(id string) (err error) {
s.Lock()
defer s.Unlock()
content := &spacesyncproto.SpaceSettingsContent_ObjectDelete{
ObjectDelete: &spacesyncproto.ObjectDelete{Id: id},
}
@ -127,8 +148,6 @@ func (s *settingsDocument) DeleteObject(id string) (err error) {
if err != nil {
return
}
s.Lock()
defer s.Unlock()
_, err = s.AddContent(context.Background(), tree.SignableChangeContent{
Data: res,
Key: s.account.Account().SignKey,

View File

@ -156,7 +156,7 @@ func (s *space) Init(ctx context.Context) (err error) {
if err != nil {
return
}
s.settingsDocument.Init()
s.settingsDocument.Refresh()
s.aclList = syncacl.NewSyncACL(aclList, s.syncService.StreamPool())
objectGetter := newCommonSpaceGetter(s.id, s.aclList, s.cache, s.settingsDocument)
s.syncService.Init(objectGetter)