From 89fa4d71a3970cd54214a48bdfeb859949b909fe Mon Sep 17 00:00:00 2001 From: mcrakhman Date: Mon, 20 Feb 2023 23:47:32 +0100 Subject: [PATCH] Create methods for deleting space --- commonspace/headsync/diffsyncer.go | 8 +- commonspace/headsync/diffsyncer_test.go | 4 +- commonspace/headsync/headsync.go | 6 +- commonspace/headsync/headsync_test.go | 4 +- .../headsync/mock_headsync/mock_headsync.go | 4 +- commonspace/settings/deleter.go | 6 +- commonspace/settings/deleter_test.go | 4 +- commonspace/settings/deletionmanager.go | 10 +-- commonspace/settings/settings.go | 83 ++++++++++++++----- commonspace/settings/settings_test.go | 6 +- .../settings/settingsstate/changefactory.go | 64 ++++++++++++++ .../deletionstate.go | 41 +++------ .../deletionstate_test.go | 6 +- .../mock_settingsstate}/mock_deletionstate.go | 12 +-- .../settingsstate.go} | 2 +- .../{ => settingsstate}/statebuilder.go | 16 ++-- commonspace/space.go | 15 +++- 17 files changed, 193 insertions(+), 98 deletions(-) create mode 100644 commonspace/settings/settingsstate/changefactory.go rename commonspace/settings/{deletionstate => settingsstate}/deletionstate.go (67%) rename commonspace/settings/{deletionstate => settingsstate}/deletionstate_test.go (96%) rename commonspace/settings/{deletionstate/mock_deletionstate => settingsstate/mock_settingsstate}/mock_deletionstate.go (92%) rename commonspace/settings/{state.go => settingsstate/settingsstate.go} (84%) rename commonspace/settings/{ => settingsstate}/statebuilder.go (85%) diff --git a/commonspace/headsync/diffsyncer.go b/commonspace/headsync/diffsyncer.go index be12d6bf..141509d4 100644 --- a/commonspace/headsync/diffsyncer.go +++ b/commonspace/headsync/diffsyncer.go @@ -8,7 +8,7 @@ import ( "github.com/anytypeio/any-sync/commonspace/object/tree/synctree" "github.com/anytypeio/any-sync/commonspace/object/treegetter" "github.com/anytypeio/any-sync/commonspace/peermanager" - "github.com/anytypeio/any-sync/commonspace/settings/deletionstate" + "github.com/anytypeio/any-sync/commonspace/settings/settingsstate" "github.com/anytypeio/any-sync/commonspace/spacestorage" "github.com/anytypeio/any-sync/commonspace/spacesyncproto" "github.com/anytypeio/any-sync/commonspace/syncstatus" @@ -22,7 +22,7 @@ type DiffSyncer interface { Sync(ctx context.Context) error RemoveObjects(ids []string) UpdateHeads(id string, heads []string) - Init(deletionState deletionstate.DeletionState) + Init(deletionState settingsstate.ObjectDeletionState) } func newDiffSyncer( @@ -54,11 +54,11 @@ type diffSyncer struct { storage spacestorage.SpaceStorage clientFactory spacesyncproto.ClientFactory log logger.CtxLogger - deletionState deletionstate.DeletionState + deletionState settingsstate.ObjectDeletionState syncStatus syncstatus.StatusUpdater } -func (d *diffSyncer) Init(deletionState deletionstate.DeletionState) { +func (d *diffSyncer) Init(deletionState settingsstate.ObjectDeletionState) { d.deletionState = deletionState d.deletionState.AddObserver(d.RemoveObjects) } diff --git a/commonspace/headsync/diffsyncer_test.go b/commonspace/headsync/diffsyncer_test.go index d53af0ac..3f78d878 100644 --- a/commonspace/headsync/diffsyncer_test.go +++ b/commonspace/headsync/diffsyncer_test.go @@ -12,7 +12,7 @@ import ( mock_treestorage "github.com/anytypeio/any-sync/commonspace/object/tree/treestorage/mock_treestorage" "github.com/anytypeio/any-sync/commonspace/object/treegetter/mock_treegetter" "github.com/anytypeio/any-sync/commonspace/peermanager/mock_peermanager" - "github.com/anytypeio/any-sync/commonspace/settings/deletionstate/mock_deletionstate" + "github.com/anytypeio/any-sync/commonspace/settings/settingsstate/mock_settingsstate" "github.com/anytypeio/any-sync/commonspace/spacestorage/mock_spacestorage" "github.com/anytypeio/any-sync/commonspace/spacesyncproto" "github.com/anytypeio/any-sync/commonspace/spacesyncproto/mock_spacesyncproto" @@ -106,7 +106,7 @@ func TestDiffSyncer_Sync(t *testing.T) { factory := spacesyncproto.ClientFactoryFunc(func(cc drpc.Conn) spacesyncproto.DRPCSpaceSyncClient { return clientMock }) - delState := mock_deletionstate.NewMockDeletionState(ctrl) + delState := mock_settingsstate.NewMockDeletionState(ctrl) spaceId := "spaceId" aclRootId := "aclRootId" l := logger.NewNamed(spaceId) diff --git a/commonspace/headsync/headsync.go b/commonspace/headsync/headsync.go index dd920364..aab03b18 100644 --- a/commonspace/headsync/headsync.go +++ b/commonspace/headsync/headsync.go @@ -7,7 +7,7 @@ import ( "github.com/anytypeio/any-sync/app/logger" "github.com/anytypeio/any-sync/commonspace/object/treegetter" "github.com/anytypeio/any-sync/commonspace/peermanager" - "github.com/anytypeio/any-sync/commonspace/settings/deletionstate" + "github.com/anytypeio/any-sync/commonspace/settings/settingsstate" "github.com/anytypeio/any-sync/commonspace/spacestorage" "github.com/anytypeio/any-sync/commonspace/spacesyncproto" "github.com/anytypeio/any-sync/commonspace/syncstatus" @@ -24,7 +24,7 @@ type TreeHeads struct { } type HeadSync interface { - Init(objectIds []string, deletionState deletionstate.DeletionState) + Init(objectIds []string, deletionState settingsstate.ObjectDeletionState) UpdateHeads(id string, heads []string) HandleRangeRequest(ctx context.Context, req *spacesyncproto.HeadSyncRequest) (resp *spacesyncproto.HeadSyncResponse, err error) @@ -81,7 +81,7 @@ func NewHeadSync( } } -func (d *headSync) Init(objectIds []string, deletionState deletionstate.DeletionState) { +func (d *headSync) Init(objectIds []string, deletionState settingsstate.ObjectDeletionState) { d.fillDiff(objectIds) d.syncer.Init(deletionState) d.periodicSync.Run() diff --git a/commonspace/headsync/headsync_test.go b/commonspace/headsync/headsync_test.go index 2db23aff..7070bf5f 100644 --- a/commonspace/headsync/headsync_test.go +++ b/commonspace/headsync/headsync_test.go @@ -6,7 +6,7 @@ import ( "github.com/anytypeio/any-sync/app/logger" "github.com/anytypeio/any-sync/commonspace/headsync/mock_headsync" "github.com/anytypeio/any-sync/commonspace/object/tree/treestorage/mock_treestorage" - "github.com/anytypeio/any-sync/commonspace/settings/deletionstate/mock_deletionstate" + "github.com/anytypeio/any-sync/commonspace/settings/settingsstate/mock_settingsstate" "github.com/anytypeio/any-sync/commonspace/spacestorage/mock_spacestorage" "github.com/anytypeio/any-sync/util/periodicsync/mock_periodicsync" "github.com/golang/mock/gomock" @@ -24,7 +24,7 @@ func TestDiffService(t *testing.T) { treeStorageMock := mock_treestorage.NewMockTreeStorage(ctrl) diffMock := mock_ldiff.NewMockDiff(ctrl) syncer := mock_headsync.NewMockDiffSyncer(ctrl) - delState := mock_deletionstate.NewMockDeletionState(ctrl) + delState := mock_settingsstate.NewMockDeletionState(ctrl) syncPeriod := 1 initId := "initId" diff --git a/commonspace/headsync/mock_headsync/mock_headsync.go b/commonspace/headsync/mock_headsync/mock_headsync.go index 492d2b32..b0781825 100644 --- a/commonspace/headsync/mock_headsync/mock_headsync.go +++ b/commonspace/headsync/mock_headsync/mock_headsync.go @@ -8,7 +8,7 @@ import ( context "context" reflect "reflect" - deletionstate "github.com/anytypeio/any-sync/commonspace/settings/deletionstate" + deletionstate "github.com/anytypeio/any-sync/commonspace/settings/settingsstate" gomock "github.com/golang/mock/gomock" ) @@ -36,7 +36,7 @@ func (m *MockDiffSyncer) EXPECT() *MockDiffSyncerMockRecorder { } // Init mocks base method. -func (m *MockDiffSyncer) Init(arg0 deletionstate.DeletionState) { +func (m *MockDiffSyncer) Init(arg0 deletionstate.ObjectDeletionState) { m.ctrl.T.Helper() m.ctrl.Call(m, "Init", arg0) } diff --git a/commonspace/settings/deleter.go b/commonspace/settings/deleter.go index 967cd440..55f026c1 100644 --- a/commonspace/settings/deleter.go +++ b/commonspace/settings/deleter.go @@ -3,7 +3,7 @@ package settings import ( "context" "github.com/anytypeio/any-sync/commonspace/object/treegetter" - "github.com/anytypeio/any-sync/commonspace/settings/deletionstate" + "github.com/anytypeio/any-sync/commonspace/settings/settingsstate" "github.com/anytypeio/any-sync/commonspace/spacestorage" "go.uber.org/zap" ) @@ -14,11 +14,11 @@ type Deleter interface { type deleter struct { st spacestorage.SpaceStorage - state deletionstate.DeletionState + state settingsstate.ObjectDeletionState getter treegetter.TreeGetter } -func newDeleter(st spacestorage.SpaceStorage, state deletionstate.DeletionState, getter treegetter.TreeGetter) Deleter { +func newDeleter(st spacestorage.SpaceStorage, state settingsstate.ObjectDeletionState, getter treegetter.TreeGetter) Deleter { return &deleter{st, state, getter} } diff --git a/commonspace/settings/deleter_test.go b/commonspace/settings/deleter_test.go index 8ddc43a2..fc33a168 100644 --- a/commonspace/settings/deleter_test.go +++ b/commonspace/settings/deleter_test.go @@ -3,7 +3,7 @@ package settings import ( "fmt" "github.com/anytypeio/any-sync/commonspace/object/treegetter/mock_treegetter" - "github.com/anytypeio/any-sync/commonspace/settings/deletionstate/mock_deletionstate" + "github.com/anytypeio/any-sync/commonspace/settings/settingsstate/mock_settingsstate" "github.com/anytypeio/any-sync/commonspace/spacestorage" "github.com/anytypeio/any-sync/commonspace/spacestorage/mock_spacestorage" "github.com/golang/mock/gomock" @@ -14,7 +14,7 @@ func TestDeleter_Delete(t *testing.T) { ctrl := gomock.NewController(t) treeGetter := mock_treegetter.NewMockTreeGetter(ctrl) st := mock_spacestorage.NewMockSpaceStorage(ctrl) - delState := mock_deletionstate.NewMockDeletionState(ctrl) + delState := mock_settingsstate.NewMockDeletionState(ctrl) deleter := newDeleter(st, delState, treeGetter) diff --git a/commonspace/settings/deletionmanager.go b/commonspace/settings/deletionmanager.go index a864bfef..e93ec4f9 100644 --- a/commonspace/settings/deletionmanager.go +++ b/commonspace/settings/deletionmanager.go @@ -2,7 +2,7 @@ package settings import ( "github.com/anytypeio/any-sync/commonspace/object/treegetter" - "github.com/anytypeio/any-sync/commonspace/settings/deletionstate" + "github.com/anytypeio/any-sync/commonspace/settings/settingsstate" "time" ) @@ -15,13 +15,13 @@ type SpaceDeleter interface { } type DeletionManager interface { - UpdateState(state *State) (err error) + UpdateState(state *settingsstate.State) (err error) } func newDeletionManager( spaceId string, deletionInterval time.Duration, - deletionState deletionstate.DeletionState, + deletionState settingsstate.ObjectDeletionState, provider SpaceIdsProvider, onSpaceDelete func()) DeletionManager { return &deletionManager{ @@ -34,7 +34,7 @@ func newDeletionManager( } type deletionManager struct { - deletionState deletionstate.DeletionState + deletionState settingsstate.ObjectDeletionState provider SpaceIdsProvider treeGetter treegetter.TreeGetter deletionInterval time.Duration @@ -42,7 +42,7 @@ type deletionManager struct { onSpaceDelete func() } -func (d *deletionManager) UpdateState(state *State) (err error) { +func (d *deletionManager) UpdateState(state *settingsstate.State) (err error) { err = d.deletionState.Add(state.DeletedIds) if err != nil { log.Warn("failed to add deleted ids to deletion state") diff --git a/commonspace/settings/settings.go b/commonspace/settings/settings.go index a252901d..5efddeae 100644 --- a/commonspace/settings/settings.go +++ b/commonspace/settings/settings.go @@ -10,7 +10,7 @@ import ( "github.com/anytypeio/any-sync/commonspace/object/tree/synctree" "github.com/anytypeio/any-sync/commonspace/object/tree/synctree/updatelistener" "github.com/anytypeio/any-sync/commonspace/object/treegetter" - "github.com/anytypeio/any-sync/commonspace/settings/deletionstate" + "github.com/anytypeio/any-sync/commonspace/settings/settingsstate" spacestorage "github.com/anytypeio/any-sync/commonspace/spacestorage" "go.uber.org/zap" "time" @@ -24,12 +24,16 @@ type SettingsObject interface { synctree.SyncTree Init(ctx context.Context) (err error) DeleteObject(id string) (err error) + DeleteSpace(t time.Time) (err error) + RestoreSpace() (err error) } var ( - ErrDeleteSelf = errors.New("cannot delete self") - ErrAlreadyDeleted = errors.New("the object is already deleted") - ErrObjDoesNotExist = errors.New("the object does not exist") + ErrDeleteSelf = errors.New("cannot delete self") + ErrAlreadyDeleted = errors.New("the object is already deleted") + ErrObjDoesNotExist = errors.New("the object does not exist") + ErrMarkedDeleted = errors.New("this space is already marked deleted") + ErrMarkedNotDeleted = errors.New("this space is not marked not deleted") ) type BuildTreeFunc func(ctx context.Context, id string, listener updatelistener.UpdateListener) (t synctree.SyncTree, err error) @@ -39,13 +43,14 @@ type Deps struct { Account accountservice.Service TreeGetter treegetter.TreeGetter Store spacestorage.SpaceStorage - DeletionState deletionstate.DeletionState + DeletionState settingsstate.ObjectDeletionState Provider SpaceIdsProvider OnSpaceDelete func() // testing dependencies - builder StateBuilder - del Deleter - delManager DeletionManager + builder settingsstate.StateBuilder + del Deleter + delManager DeletionManager + changeFactory settingsstate.ChangeFactory } type settingsObject struct { @@ -54,19 +59,22 @@ type settingsObject struct { spaceId string treeGetter treegetter.TreeGetter store spacestorage.SpaceStorage - builder StateBuilder + builder settingsstate.StateBuilder buildFunc BuildTreeFunc loop *deleteLoop - deletionState deletionstate.DeletionState + state *settingsstate.State + deletionState settingsstate.ObjectDeletionState deletionManager DeletionManager + changeFactory settingsstate.ChangeFactory } func NewSettingsObject(deps Deps, spaceId string) (obj SettingsObject) { var ( deleter Deleter deletionManager DeletionManager - builder StateBuilder + builder settingsstate.StateBuilder + changeFactory settingsstate.ChangeFactory ) if deps.del == nil { deleter = newDeleter(deps.Store, deps.DeletionState, deps.TreeGetter) @@ -79,10 +87,15 @@ func NewSettingsObject(deps Deps, spaceId string) (obj SettingsObject) { deletionManager = deps.delManager } if deps.builder == nil { - builder = newStateBuilder() + builder = settingsstate.NewStateBuilder() } else { builder = deps.builder } + if deps.changeFactory == nil { + changeFactory = settingsstate.NewChangeFactory() + } else { + changeFactory = deps.changeFactory + } loop := newDeleteLoop(func() { deleter.Delete() @@ -101,18 +114,20 @@ func NewSettingsObject(deps Deps, spaceId string) (obj SettingsObject) { buildFunc: deps.BuildFunc, builder: builder, deletionManager: deletionManager, + changeFactory: changeFactory, } obj = s return } func (s *settingsObject) updateIds(tr objecttree.ObjectTree, isUpdate bool) { - state, err := s.builder.Build(tr, isUpdate) + var err error + s.state, err = s.builder.Build(tr, s.state, isUpdate) if err != nil { log.Error("failed to build state", zap.Error(err)) return } - if err = s.deletionManager.UpdateState(state); err != nil { + if err = s.deletionManager.UpdateState(s.state); err != nil { log.Error("failed to update state", zap.Error(err)) } } @@ -145,12 +160,36 @@ func (s *settingsObject) Close() error { return s.SyncTree.Close() } -func (s *settingsObject) DeleteAccount() (err error) { - return nil +func (s *settingsObject) DeleteSpace(t time.Time) (err error) { + s.Lock() + defer s.Unlock() + if !s.state.SpaceDeletionDate.IsZero() { + return ErrMarkedDeleted + } + + // TODO: add snapshot logic + res, err := s.changeFactory.CreateSpaceDeleteChange(t, s.state, false) + if err != nil { + return + } + + return s.addContent(res) } -func (s *settingsObject) RestoreAccount() (err error) { - return nil +func (s *settingsObject) RestoreSpace() (err error) { + s.Lock() + defer s.Unlock() + if s.state.SpaceDeletionDate.IsZero() { + return ErrMarkedNotDeleted + } + + // TODO: add snapshot logic + res, err := s.changeFactory.CreateSpaceRestoreChange(s.state, false) + if err != nil { + return + } + + return s.addContent(res) } func (s *settingsObject) DeleteObject(id string) (err error) { @@ -171,14 +210,18 @@ func (s *settingsObject) DeleteObject(id string) (err error) { } // TODO: add snapshot logic - res, err := s.deletionState.CreateDeleteChange(id, false) + res, err := s.changeFactory.CreateObjectDeleteChange(id, s.state, false) if err != nil { return } + return s.addContent(res) +} + +func (s *settingsObject) addContent(data []byte) (err error) { accountData := s.account.Account() _, err = s.AddContent(context.Background(), objecttree.SignableChangeContent{ - Data: res, + Data: data, Key: accountData.SignKey, Identity: accountData.Identity, IsSnapshot: false, diff --git a/commonspace/settings/settings_test.go b/commonspace/settings/settings_test.go index 079253ff..cc87b428 100644 --- a/commonspace/settings/settings_test.go +++ b/commonspace/settings/settings_test.go @@ -9,7 +9,7 @@ import ( "github.com/anytypeio/any-sync/commonspace/object/tree/synctree/mock_synctree" "github.com/anytypeio/any-sync/commonspace/object/tree/synctree/updatelistener" "github.com/anytypeio/any-sync/commonspace/object/treegetter/mock_treegetter" - "github.com/anytypeio/any-sync/commonspace/settings/deletionstate/mock_deletionstate" + "github.com/anytypeio/any-sync/commonspace/settings/settingsstate/mock_settingsstate" "github.com/anytypeio/any-sync/commonspace/settings/mock_settings" "github.com/anytypeio/any-sync/commonspace/spacestorage/mock_spacestorage" "github.com/anytypeio/any-sync/util/keys/asymmetric/signingkey" @@ -49,7 +49,7 @@ type settingsFixture struct { provider *mock_settings.MockDeletedIdsProvider deleter *mock_settings.MockDeleter syncTree *mock_synctree.MockSyncTree - delState *mock_deletionstate.MockDeletionState + delState *mock_settingsstate.MockDeletionState account *mock_accountservice.MockService } @@ -61,7 +61,7 @@ func newSettingsFixture(t *testing.T) *settingsFixture { acc := mock_accountservice.NewMockService(ctrl) treeGetter := mock_treegetter.NewMockTreeGetter(ctrl) st := mock_spacestorage.NewMockSpaceStorage(ctrl) - delState := mock_deletionstate.NewMockDeletionState(ctrl) + delState := mock_settingsstate.NewMockDeletionState(ctrl) prov := mock_settings.NewMockDeletedIdsProvider(ctrl) syncTree := mock_synctree.NewMockSyncTree(ctrl) del := mock_settings.NewMockDeleter(ctrl) diff --git a/commonspace/settings/settingsstate/changefactory.go b/commonspace/settings/settingsstate/changefactory.go new file mode 100644 index 00000000..c414878c --- /dev/null +++ b/commonspace/settings/settingsstate/changefactory.go @@ -0,0 +1,64 @@ +package settingsstate + +import ( + "github.com/anytypeio/any-sync/commonspace/spacesyncproto" + "time" +) + +type ChangeFactory interface { + CreateObjectDeleteChange(id string, state *State, isSnapshot bool) (res []byte, err error) + CreateSpaceDeleteChange(t time.Time, state *State, isSnapshot bool) (res []byte, err error) + CreateSpaceRestoreChange(state *State, isSnapshot bool) (res []byte, err error) +} + +func NewChangeFactory() ChangeFactory { + return &changeFactory{} +} + +type changeFactory struct { +} + +func (c *changeFactory) CreateObjectDeleteChange(id string, state *State, isSnapshot bool) (res []byte, err error) { + content := &spacesyncproto.SpaceSettingsContent_ObjectDelete{ + ObjectDelete: &spacesyncproto.ObjectDelete{Id: id}, + } + change := &spacesyncproto.SettingsData{ + Content: []*spacesyncproto.SpaceSettingsContent{ + {Value: content}, + }, + Snapshot: nil, + } + // TODO: add snapshot logic + res, err = change.Marshal() + return +} + +func (c *changeFactory) CreateSpaceDeleteChange(t time.Time, state *State, isSnapshot bool) (res []byte, err error) { + content := &spacesyncproto.SpaceSettingsContent_SpaceDelete{ + SpaceDelete: &spacesyncproto.SpaceDelete{Timestamp: t.UnixNano()}, + } + change := &spacesyncproto.SettingsData{ + Content: []*spacesyncproto.SpaceSettingsContent{ + {Value: content}, + }, + Snapshot: nil, + } + // TODO: add snapshot logic + res, err = change.Marshal() + return +} + +func (c *changeFactory) CreateSpaceRestoreChange(state *State, isSnapshot bool) (res []byte, err error) { + content := &spacesyncproto.SpaceSettingsContent_SpaceDelete{ + SpaceDelete: &spacesyncproto.SpaceDelete{}, + } + change := &spacesyncproto.SettingsData{ + Content: []*spacesyncproto.SpaceSettingsContent{ + {Value: content}, + }, + Snapshot: nil, + } + // TODO: add snapshot logic + res, err = change.Marshal() + return +} diff --git a/commonspace/settings/deletionstate/deletionstate.go b/commonspace/settings/settingsstate/deletionstate.go similarity index 67% rename from commonspace/settings/deletionstate/deletionstate.go rename to commonspace/settings/settingsstate/deletionstate.go index c0d700a8..16de7486 100644 --- a/commonspace/settings/deletionstate/deletionstate.go +++ b/commonspace/settings/settingsstate/deletionstate.go @@ -1,25 +1,23 @@ //go:generate mockgen -destination mock_deletionstate/mock_deletionstate.go github.com/anytypeio/any-sync/commonspace/settings/deletionstate DeletionState -package deletionstate +package settingsstate import ( "github.com/anytypeio/any-sync/commonspace/spacestorage" - "github.com/anytypeio/any-sync/commonspace/spacesyncproto" "sync" ) type StateUpdateObserver func(ids []string) -type DeletionState interface { +type ObjectDeletionState interface { AddObserver(observer StateUpdateObserver) Add(ids []string) (err error) GetQueued() (ids []string) Delete(id string) (err error) Exists(id string) bool FilterJoin(ids ...[]string) (filtered []string) - CreateDeleteChange(id string, isSnapshot bool) (res []byte, err error) } -type deletionState struct { +type objectDeletionState struct { sync.RWMutex queued map[string]struct{} deleted map[string]struct{} @@ -27,21 +25,21 @@ type deletionState struct { storage spacestorage.SpaceStorage } -func NewDeletionState(storage spacestorage.SpaceStorage) DeletionState { - return &deletionState{ +func NewObjectDeletionState(storage spacestorage.SpaceStorage) ObjectDeletionState { + return &objectDeletionState{ queued: map[string]struct{}{}, deleted: map[string]struct{}{}, storage: storage, } } -func (st *deletionState) AddObserver(observer StateUpdateObserver) { +func (st *objectDeletionState) AddObserver(observer StateUpdateObserver) { st.Lock() defer st.Unlock() st.stateUpdateObservers = append(st.stateUpdateObservers, observer) } -func (st *deletionState) Add(ids []string) (err error) { +func (st *objectDeletionState) Add(ids []string) (err error) { st.Lock() defer func() { st.Unlock() @@ -83,7 +81,7 @@ func (st *deletionState) Add(ids []string) (err error) { return } -func (st *deletionState) GetQueued() (ids []string) { +func (st *objectDeletionState) GetQueued() (ids []string) { st.RLock() defer st.RUnlock() ids = make([]string, 0, len(st.queued)) @@ -93,7 +91,7 @@ func (st *deletionState) GetQueued() (ids []string) { return } -func (st *deletionState) Delete(id string) (err error) { +func (st *objectDeletionState) Delete(id string) (err error) { st.Lock() defer st.Unlock() delete(st.queued, id) @@ -105,13 +103,13 @@ func (st *deletionState) Delete(id string) (err error) { return } -func (st *deletionState) Exists(id string) bool { +func (st *objectDeletionState) Exists(id string) bool { st.RLock() defer st.RUnlock() return st.exists(id) } -func (st *deletionState) FilterJoin(ids ...[]string) (filtered []string) { +func (st *objectDeletionState) FilterJoin(ids ...[]string) (filtered []string) { st.RLock() defer st.RUnlock() filter := func(ids []string) { @@ -127,22 +125,7 @@ func (st *deletionState) FilterJoin(ids ...[]string) (filtered []string) { return } -func (st *deletionState) CreateDeleteChange(id string, isSnapshot bool) (res []byte, err error) { - content := &spacesyncproto.SpaceSettingsContent_ObjectDelete{ - ObjectDelete: &spacesyncproto.ObjectDelete{Id: id}, - } - change := &spacesyncproto.SettingsData{ - Content: []*spacesyncproto.SpaceSettingsContent{ - {Value: content}, - }, - Snapshot: nil, - } - // TODO: add snapshot logic - res, err = change.Marshal() - return -} - -func (st *deletionState) exists(id string) bool { +func (st *objectDeletionState) exists(id string) bool { if _, exists := st.deleted[id]; exists { return true } diff --git a/commonspace/settings/deletionstate/deletionstate_test.go b/commonspace/settings/settingsstate/deletionstate_test.go similarity index 96% rename from commonspace/settings/deletionstate/deletionstate_test.go rename to commonspace/settings/settingsstate/deletionstate_test.go index 82c68122..31b14a0d 100644 --- a/commonspace/settings/deletionstate/deletionstate_test.go +++ b/commonspace/settings/settingsstate/deletionstate_test.go @@ -1,4 +1,4 @@ -package deletionstate +package settingsstate import ( "github.com/anytypeio/any-sync/commonspace/spacestorage" @@ -11,14 +11,14 @@ import ( type fixture struct { ctrl *gomock.Controller - delState *deletionState + delState *objectDeletionState spaceStorage *mock_spacestorage.MockSpaceStorage } func newFixture(t *testing.T) *fixture { ctrl := gomock.NewController(t) spaceStorage := mock_spacestorage.NewMockSpaceStorage(ctrl) - delState := NewDeletionState(spaceStorage).(*deletionState) + delState := NewObjectDeletionState(spaceStorage).(*objectDeletionState) return &fixture{ ctrl: ctrl, delState: delState, diff --git a/commonspace/settings/deletionstate/mock_deletionstate/mock_deletionstate.go b/commonspace/settings/settingsstate/mock_settingsstate/mock_deletionstate.go similarity index 92% rename from commonspace/settings/deletionstate/mock_deletionstate/mock_deletionstate.go rename to commonspace/settings/settingsstate/mock_settingsstate/mock_deletionstate.go index 33ea472d..0e9aa0c0 100644 --- a/commonspace/settings/deletionstate/mock_deletionstate/mock_deletionstate.go +++ b/commonspace/settings/settingsstate/mock_settingsstate/mock_deletionstate.go @@ -1,17 +1,17 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/anytypeio/any-sync/commonspace/settings/deletionstate (interfaces: DeletionState) +// Source: github.com/anytypeio/any-sync/commonspace/settings/deletionstate (interfaces: ObjectDeletionState) // Package mock_deletionstate is a generated GoMock package. -package mock_deletionstate +package mock_settingsstate import ( reflect "reflect" - deletionstate "github.com/anytypeio/any-sync/commonspace/settings/deletionstate" + deletionstate "github.com/anytypeio/any-sync/commonspace/settings/settingsstate" gomock "github.com/golang/mock/gomock" ) -// MockDeletionState is a mock of DeletionState interface. +// MockDeletionState is a mock of ObjectDeletionState interface. type MockDeletionState struct { ctrl *gomock.Controller recorder *MockDeletionStateMockRecorder @@ -61,7 +61,7 @@ func (mr *MockDeletionStateMockRecorder) AddObserver(arg0 interface{}) *gomock.C } // CreateDeleteChange mocks base method. -func (m *MockDeletionState) CreateDeleteChange(arg0 string, arg1 bool) ([]byte, error) { +func (m *MockDeletionState) CreateObjectDeleteChange(arg0 string, arg1 bool) ([]byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "CreateDeleteChange", arg0, arg1) ret0, _ := ret[0].([]byte) @@ -72,7 +72,7 @@ func (m *MockDeletionState) CreateDeleteChange(arg0 string, arg1 bool) ([]byte, // CreateDeleteChange indicates an expected call of CreateDeleteChange. func (mr *MockDeletionStateMockRecorder) CreateDeleteChange(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDeleteChange", reflect.TypeOf((*MockDeletionState)(nil).CreateDeleteChange), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDeleteChange", reflect.TypeOf((*MockDeletionState)(nil).CreateObjectDeleteChange), arg0, arg1) } // Delete mocks base method. diff --git a/commonspace/settings/state.go b/commonspace/settings/settingsstate/settingsstate.go similarity index 84% rename from commonspace/settings/state.go rename to commonspace/settings/settingsstate/settingsstate.go index 0821fb7e..6263b089 100644 --- a/commonspace/settings/state.go +++ b/commonspace/settings/settingsstate/settingsstate.go @@ -1,4 +1,4 @@ -package settings +package settingsstate import "time" diff --git a/commonspace/settings/statebuilder.go b/commonspace/settings/settingsstate/statebuilder.go similarity index 85% rename from commonspace/settings/statebuilder.go rename to commonspace/settings/settingsstate/statebuilder.go index 7f1e418a..5e5087a7 100644 --- a/commonspace/settings/statebuilder.go +++ b/commonspace/settings/settingsstate/statebuilder.go @@ -1,4 +1,4 @@ -package settings +package settingsstate import ( "github.com/anytypeio/any-sync/commonspace/object/tree/objecttree" @@ -8,24 +8,18 @@ import ( ) type StateBuilder interface { - Build(tree objecttree.ObjectTree, isUpdate bool) (*State, error) + Build(tree objecttree.ObjectTree, state *State, isUpdate bool) (*State, error) } -func newStateBuilder() StateBuilder { +func NewStateBuilder() StateBuilder { return &stateBuilder{} } type stateBuilder struct { - state *State } -func (s *stateBuilder) Build(tr objecttree.ObjectTree, isUpdate bool) (state *State, err error) { - state = s.state - defer func() { - if err == nil { - s.state = state - } - }() +func (s *stateBuilder) Build(tr objecttree.ObjectTree, oldState *State, isUpdate bool) (state *State, err error) { + state = oldState if !isUpdate || state == nil { state = &State{} diff --git a/commonspace/space.go b/commonspace/space.go index 2e9f30d6..26849049 100644 --- a/commonspace/space.go +++ b/commonspace/space.go @@ -18,7 +18,7 @@ import ( "github.com/anytypeio/any-sync/commonspace/objectsync" "github.com/anytypeio/any-sync/commonspace/peermanager" "github.com/anytypeio/any-sync/commonspace/settings" - "github.com/anytypeio/any-sync/commonspace/settings/deletionstate" + "github.com/anytypeio/any-sync/commonspace/settings/settingsstate" "github.com/anytypeio/any-sync/commonspace/spacestorage" "github.com/anytypeio/any-sync/commonspace/spacesyncproto" "github.com/anytypeio/any-sync/commonspace/syncstatus" @@ -99,6 +99,9 @@ type Space interface { DeleteTree(ctx context.Context, id string) (err error) BuildHistoryTree(ctx context.Context, id string, opts HistoryTreeOpts) (t objecttree.HistoryTree, err error) + DeleteSpace(ctx context.Context, t time.Time) (err error) + RestoreSpace(ctx context.Context) (err error) + HeadSync() headsync.HeadSync ObjectSync() objectsync.ObjectSync SyncStatus() syncstatus.StatusUpdater @@ -191,7 +194,7 @@ func (s *space) Init(ctx context.Context) (err error) { s.aclList = syncacl.NewSyncAcl(aclList, s.objectSync.MessagePool()) s.cache.AddObject(s.aclList) - deletionState := deletionstate.NewDeletionState(s.storage) + deletionState := settingsstate.NewObjectDeletionState(s.storage) deps := settings.Deps{ BuildFunc: func(ctx context.Context, id string, listener updatelistener.UpdateListener) (t synctree.SyncTree, err error) { res, err := s.BuildTree(ctx, id, BuildTreeOpts{ @@ -365,6 +368,14 @@ func (s *space) DeleteTree(ctx context.Context, id string) (err error) { return s.settingsObject.DeleteObject(id) } +func (s *space) DeleteSpace(ctx context.Context, t time.Time) (err error) { + return s.settingsObject.DeleteSpace(t) +} + +func (s *space) RestoreSpace(ctx context.Context) (err error) { + return s.settingsObject.RestoreSpace() +} + func (s *space) HandleMessage(ctx context.Context, hm HandleMessage) (err error) { threadId := hm.Message.ObjectId if hm.Message.ReplyId != "" {