WIP more deletion checks
This commit is contained in:
parent
676976e7d3
commit
a5fe46e50e
@ -23,6 +23,8 @@ type Controller interface {
|
|||||||
|
|
||||||
// CreateDocument creates new document in space
|
// CreateDocument creates new document in space
|
||||||
CreateDocument(spaceId string) (id string, err error)
|
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 gets all ids of documents in space
|
||||||
AllDocumentIds(spaceId string) (ids []string, err error)
|
AllDocumentIds(spaceId string) (ids []string, err error)
|
||||||
// AddText adds text to space document
|
// 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)
|
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) {
|
func (c *controller) AllDocumentIds(spaceId string) (ids []string, err error) {
|
||||||
return c.docService.AllDocumentIds(spaceId)
|
return c.docService.AllDocumentIds(spaceId)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,10 +53,18 @@ func (s *service) CreateDocument(spaceId string) (id string, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
id = doc.Tree().ID()
|
id = doc.ID()
|
||||||
return
|
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) {
|
func (s *service) AllDocumentIds(spaceId string) (ids []string, err error) {
|
||||||
space, err := s.spaceService.GetSpace(context.Background(), spaceId)
|
space, err := s.spaceService.GetSpace(context.Background(), spaceId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -79,5 +87,5 @@ func (s *service) DumpDocumentTree(spaceId, documentId string) (dump string, err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return doc.Tree().DebugDump()
|
return doc.DebugDump()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,10 +69,7 @@ func (d *diffService) HandleRangeRequest(ctx context.Context, req *spacesyncprot
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *diffService) UpdateHeads(id string, heads []string) {
|
func (d *diffService) UpdateHeads(id string, heads []string) {
|
||||||
d.diff.Set(ldiff.Element{
|
d.syncer.UpdateHeads(id, heads)
|
||||||
Id: id,
|
|
||||||
Head: concatStrings(heads),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *diffService) AllIds() []string {
|
func (d *diffService) AllIds() []string {
|
||||||
@ -80,9 +77,6 @@ func (d *diffService) AllIds() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *diffService) RemoveObjects(ids []string) {
|
func (d *diffService) RemoveObjects(ids []string) {
|
||||||
for _, id := range ids {
|
|
||||||
d.diff.RemoveId(id)
|
|
||||||
}
|
|
||||||
d.syncer.RemoveObjects(ids)
|
d.syncer.RemoveObjects(ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import (
|
|||||||
type DiffSyncer interface {
|
type DiffSyncer interface {
|
||||||
Sync(ctx context.Context) error
|
Sync(ctx context.Context) error
|
||||||
RemoveObjects(ids []string)
|
RemoveObjects(ids []string)
|
||||||
|
UpdateHeads(id string, heads []string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDiffSyncer(
|
func newDiffSyncer(
|
||||||
@ -56,10 +57,23 @@ func (d *diffSyncer) RemoveObjects(ids []string) {
|
|||||||
d.Lock()
|
d.Lock()
|
||||||
defer d.Unlock()
|
defer d.Unlock()
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
|
d.diff.RemoveId(id)
|
||||||
d.removedIds[id] = struct{}{}
|
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 {
|
func (d *diffSyncer) Sync(ctx context.Context) error {
|
||||||
st := time.Now()
|
st := time.Now()
|
||||||
// diffing with responsible peers according to configuration
|
// diffing with responsible peers according to configuration
|
||||||
|
|||||||
@ -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/synctree/updatelistener"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
|
||||||
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
|
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DeletionState int
|
type DeletionState int
|
||||||
@ -19,7 +20,7 @@ const (
|
|||||||
|
|
||||||
type SettingsDocument interface {
|
type SettingsDocument interface {
|
||||||
tree.ObjectTree
|
tree.ObjectTree
|
||||||
Init()
|
Refresh()
|
||||||
DeleteObject(id string) (err error)
|
DeleteObject(id string) (err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,14 +38,15 @@ type Deps struct {
|
|||||||
|
|
||||||
type settingsDocument struct {
|
type settingsDocument struct {
|
||||||
tree.ObjectTree
|
tree.ObjectTree
|
||||||
account account.Service
|
account account.Service
|
||||||
spaceId string
|
spaceId string
|
||||||
deletionState map[string]DeletionState
|
deletionState map[string]DeletionState
|
||||||
treeGetter treegetter.TreeGetter
|
treeGetter treegetter.TreeGetter
|
||||||
store spacestorage.SpaceStorage
|
store spacestorage.SpaceStorage
|
||||||
lastChangeId string
|
lastChangeId string
|
||||||
prov deletedIdsProvider
|
prov deletedIdsProvider
|
||||||
removeNotifyFunc RemoveObjectsFunc
|
removeNotifyFunc RemoveObjectsFunc
|
||||||
|
deletionStateLock sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSettingsDocument(ctx context.Context, deps Deps, spaceId string) (doc SettingsDocument, err error) {
|
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
|
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) {
|
func (s *settingsDocument) Update(tr tree.ObjectTree) {
|
||||||
ids, lastId, err := s.prov.ProvideIds(tr, s.lastChangeId)
|
ids, lastId, err := s.prov.ProvideIds(tr, s.lastChangeId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -86,7 +96,7 @@ func (s *settingsDocument) Rebuild(tr tree.ObjectTree) {
|
|||||||
s.toBeDeleted(ids)
|
s.toBeDeleted(ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *settingsDocument) Init() {
|
func (s *settingsDocument) Refresh() {
|
||||||
s.Lock()
|
s.Lock()
|
||||||
defer s.Unlock()
|
defer s.Unlock()
|
||||||
s.Rebuild(s)
|
s.Rebuild(s)
|
||||||
@ -94,26 +104,37 @@ func (s *settingsDocument) Init() {
|
|||||||
|
|
||||||
func (s *settingsDocument) toBeDeleted(ids []string) {
|
func (s *settingsDocument) toBeDeleted(ids []string) {
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
|
s.deletionStateLock.Lock()
|
||||||
if state, exists := s.deletionState[id]; exists && state == DeletionStateDeleted {
|
if state, exists := s.deletionState[id]; exists && state == DeletionStateDeleted {
|
||||||
|
s.deletionStateLock.Unlock()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// if not already deleted
|
// 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 {
|
if _, err := s.store.TreeStorage(id); err == nil {
|
||||||
s.deletionState[id] = DeletionStateQueued
|
s.deletionState[id] = DeletionStateQueued
|
||||||
|
s.deletionStateLock.Unlock()
|
||||||
|
// doing this without lock
|
||||||
err := s.treeGetter.DeleteTree(context.Background(), s.spaceId, id)
|
err := s.treeGetter.DeleteTree(context.Background(), s.spaceId, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: some errors may tell us that the tree is actually deleted, so we should have more checks here
|
// TODO: some errors may tell us that the tree is actually deleted, so we should have more checks here
|
||||||
// TODO: add logging
|
// TODO: add logging
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// TODO: add loop to double check that everything that should be deleted is actually deleted
|
||||||
|
s.deletionStateLock.Lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
s.deletionState[id] = DeletionStateDeleted
|
s.deletionState[id] = DeletionStateDeleted
|
||||||
|
s.deletionStateLock.Unlock()
|
||||||
}
|
}
|
||||||
// notifying about removal
|
// notifying about removal
|
||||||
s.removeNotifyFunc(ids)
|
s.removeNotifyFunc(ids)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *settingsDocument) DeleteObject(id string) (err error) {
|
func (s *settingsDocument) DeleteObject(id string) (err error) {
|
||||||
|
s.Lock()
|
||||||
|
defer s.Unlock()
|
||||||
content := &spacesyncproto.SpaceSettingsContent_ObjectDelete{
|
content := &spacesyncproto.SpaceSettingsContent_ObjectDelete{
|
||||||
ObjectDelete: &spacesyncproto.ObjectDelete{Id: id},
|
ObjectDelete: &spacesyncproto.ObjectDelete{Id: id},
|
||||||
}
|
}
|
||||||
@ -127,8 +148,6 @@ func (s *settingsDocument) DeleteObject(id string) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.Lock()
|
|
||||||
defer s.Unlock()
|
|
||||||
_, err = s.AddContent(context.Background(), tree.SignableChangeContent{
|
_, err = s.AddContent(context.Background(), tree.SignableChangeContent{
|
||||||
Data: res,
|
Data: res,
|
||||||
Key: s.account.Account().SignKey,
|
Key: s.account.Account().SignKey,
|
||||||
|
|||||||
@ -156,7 +156,7 @@ func (s *space) Init(ctx context.Context) (err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.settingsDocument.Init()
|
s.settingsDocument.Refresh()
|
||||||
s.aclList = syncacl.NewSyncACL(aclList, s.syncService.StreamPool())
|
s.aclList = syncacl.NewSyncACL(aclList, s.syncService.StreamPool())
|
||||||
objectGetter := newCommonSpaceGetter(s.id, s.aclList, s.cache, s.settingsDocument)
|
objectGetter := newCommonSpaceGetter(s.id, s.aclList, s.cache, s.settingsDocument)
|
||||||
s.syncService.Init(objectGetter)
|
s.syncService.Init(objectGetter)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user