mirror of
https://github.com/anyproto/any-sync.git
synced 2025-06-10 18:10:54 +09:00
Moving parts, refactoring for deletion
This commit is contained in:
parent
e02abc153c
commit
17a6f7cb55
26 changed files with 412 additions and 526 deletions
|
@ -1,61 +0,0 @@
|
|||
package settings
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
const deleteLoopInterval = time.Second * 20
|
||||
|
||||
type deleteLoop struct {
|
||||
deleteCtx context.Context
|
||||
deleteCancel context.CancelFunc
|
||||
deleteChan chan struct{}
|
||||
deleteFunc func()
|
||||
loopDone chan struct{}
|
||||
}
|
||||
|
||||
func newDeleteLoop(deleteFunc func()) *deleteLoop {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
return &deleteLoop{
|
||||
deleteCtx: ctx,
|
||||
deleteCancel: cancel,
|
||||
deleteChan: make(chan struct{}, 1),
|
||||
deleteFunc: deleteFunc,
|
||||
loopDone: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (dl *deleteLoop) Run() {
|
||||
go dl.loop()
|
||||
}
|
||||
|
||||
func (dl *deleteLoop) loop() {
|
||||
defer close(dl.loopDone)
|
||||
dl.deleteFunc()
|
||||
ticker := time.NewTicker(deleteLoopInterval)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-dl.deleteCtx.Done():
|
||||
return
|
||||
case <-dl.deleteChan:
|
||||
dl.deleteFunc()
|
||||
ticker.Reset(deleteLoopInterval)
|
||||
case <-ticker.C:
|
||||
dl.deleteFunc()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (dl *deleteLoop) notify() {
|
||||
select {
|
||||
case dl.deleteChan <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
func (dl *deleteLoop) Close() {
|
||||
dl.deleteCancel()
|
||||
<-dl.loopDone
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
package settings
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anyproto/any-sync/commonspace/deletionstate"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treestorage"
|
||||
"github.com/anyproto/any-sync/commonspace/object/treemanager"
|
||||
"github.com/anyproto/any-sync/commonspace/spacestorage"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type Deleter interface {
|
||||
Delete()
|
||||
}
|
||||
|
||||
type deleter struct {
|
||||
st spacestorage.SpaceStorage
|
||||
state deletionstate.ObjectDeletionState
|
||||
getter treemanager.TreeManager
|
||||
}
|
||||
|
||||
func newDeleter(st spacestorage.SpaceStorage, state deletionstate.ObjectDeletionState, getter treemanager.TreeManager) Deleter {
|
||||
return &deleter{st, state, getter}
|
||||
}
|
||||
|
||||
func (d *deleter) Delete() {
|
||||
var (
|
||||
allQueued = d.state.GetQueued()
|
||||
spaceId = d.st.Id()
|
||||
)
|
||||
for _, id := range allQueued {
|
||||
log := log.With(zap.String("treeId", id), zap.String("spaceId", spaceId))
|
||||
shouldDelete, err := d.tryMarkDeleted(spaceId, id)
|
||||
if !shouldDelete {
|
||||
if err != nil {
|
||||
log.Error("failed to mark object as deleted", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
err = d.getter.DeleteTree(context.Background(), spaceId, id)
|
||||
if err != nil && err != spacestorage.ErrTreeStorageAlreadyDeleted {
|
||||
log.Error("failed to delete object", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
}
|
||||
err = d.state.Delete(id)
|
||||
if err != nil {
|
||||
log.Error("failed to mark object as deleted", zap.Error(err))
|
||||
}
|
||||
log.Debug("object successfully deleted", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
func (d *deleter) tryMarkDeleted(spaceId, treeId string) (bool, error) {
|
||||
_, err := d.st.TreeStorage(treeId)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
if err != treestorage.ErrUnknownTreeId {
|
||||
return false, err
|
||||
}
|
||||
return false, d.getter.MarkTreeDeleted(context.Background(), spaceId, treeId)
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
package settings
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/anyproto/any-sync/commonspace/deletionstate/mock_deletionstate"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treestorage"
|
||||
"github.com/anyproto/any-sync/commonspace/object/treemanager/mock_treemanager"
|
||||
"github.com/anyproto/any-sync/commonspace/spacestorage/mock_spacestorage"
|
||||
"go.uber.org/mock/gomock"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDeleter_Delete(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
treeManager := mock_treemanager.NewMockTreeManager(ctrl)
|
||||
st := mock_spacestorage.NewMockSpaceStorage(ctrl)
|
||||
delState := mock_deletionstate.NewMockObjectDeletionState(ctrl)
|
||||
|
||||
deleter := newDeleter(st, delState, treeManager)
|
||||
|
||||
t.Run("deleter delete mark deleted success", func(t *testing.T) {
|
||||
id := "id"
|
||||
spaceId := "spaceId"
|
||||
delState.EXPECT().GetQueued().Return([]string{id})
|
||||
st.EXPECT().Id().Return(spaceId)
|
||||
st.EXPECT().TreeStorage(id).Return(nil, treestorage.ErrUnknownTreeId)
|
||||
treeManager.EXPECT().MarkTreeDeleted(gomock.Any(), spaceId, id).Return(nil)
|
||||
delState.EXPECT().Delete(id).Return(nil)
|
||||
|
||||
deleter.Delete()
|
||||
})
|
||||
|
||||
t.Run("deleter delete mark deleted other error", func(t *testing.T) {
|
||||
id := "id"
|
||||
spaceId := "spaceId"
|
||||
delState.EXPECT().GetQueued().Return([]string{id})
|
||||
st.EXPECT().Id().Return(spaceId)
|
||||
st.EXPECT().TreeStorage(id).Return(nil, fmt.Errorf("unknown error"))
|
||||
|
||||
deleter.Delete()
|
||||
})
|
||||
|
||||
t.Run("deleter delete mark deleted fail", func(t *testing.T) {
|
||||
id := "id"
|
||||
spaceId := "spaceId"
|
||||
delState.EXPECT().GetQueued().Return([]string{id})
|
||||
st.EXPECT().Id().Return(spaceId)
|
||||
st.EXPECT().TreeStorage(id).Return(nil, treestorage.ErrUnknownTreeId)
|
||||
treeManager.EXPECT().MarkTreeDeleted(gomock.Any(), spaceId, id).Return(fmt.Errorf("mark error"))
|
||||
|
||||
deleter.Delete()
|
||||
})
|
||||
//treeManager.EXPECT().DeleteTree(gomock.Any(), spaceId, id).Return(spacestorage.ErrTreeStorageAlreadyDeleted)
|
||||
t.Run("deleter delete success", func(t *testing.T) {
|
||||
id := "id"
|
||||
spaceId := "spaceId"
|
||||
delState.EXPECT().GetQueued().Return([]string{id})
|
||||
st.EXPECT().Id().Return(spaceId)
|
||||
st.EXPECT().TreeStorage(id).Return(nil, nil)
|
||||
treeManager.EXPECT().DeleteTree(gomock.Any(), spaceId, id).Return(nil)
|
||||
delState.EXPECT().Delete(id).Return(nil)
|
||||
|
||||
deleter.Delete()
|
||||
})
|
||||
|
||||
t.Run("deleter delete error", func(t *testing.T) {
|
||||
id := "id"
|
||||
spaceId := "spaceId"
|
||||
delState.EXPECT().GetQueued().Return([]string{id})
|
||||
st.EXPECT().Id().Return(spaceId)
|
||||
st.EXPECT().TreeStorage(id).Return(nil, nil)
|
||||
treeManager.EXPECT().DeleteTree(gomock.Any(), spaceId, id).Return(fmt.Errorf("some error"))
|
||||
|
||||
deleter.Delete()
|
||||
})
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
package settings
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anyproto/any-sync/commonspace/deletionstate"
|
||||
"github.com/anyproto/any-sync/commonspace/object/treemanager"
|
||||
"github.com/anyproto/any-sync/commonspace/settings/settingsstate"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type SpaceIdsProvider interface {
|
||||
AllIds() []string
|
||||
}
|
||||
|
||||
type DeletionManager interface {
|
||||
UpdateState(ctx context.Context, state *settingsstate.State) (err error)
|
||||
}
|
||||
|
||||
func newDeletionManager(
|
||||
spaceId string,
|
||||
settingsId string,
|
||||
isResponsible bool,
|
||||
treeManager treemanager.TreeManager,
|
||||
deletionState deletionstate.ObjectDeletionState,
|
||||
provider SpaceIdsProvider,
|
||||
onSpaceDelete func()) DeletionManager {
|
||||
return &deletionManager{
|
||||
treeManager: treeManager,
|
||||
isResponsible: isResponsible,
|
||||
spaceId: spaceId,
|
||||
settingsId: settingsId,
|
||||
deletionState: deletionState,
|
||||
provider: provider,
|
||||
onSpaceDelete: onSpaceDelete,
|
||||
}
|
||||
}
|
||||
|
||||
type deletionManager struct {
|
||||
deletionState deletionstate.ObjectDeletionState
|
||||
provider SpaceIdsProvider
|
||||
treeManager treemanager.TreeManager
|
||||
spaceId string
|
||||
settingsId string
|
||||
isResponsible bool
|
||||
onSpaceDelete func()
|
||||
}
|
||||
|
||||
func (d *deletionManager) UpdateState(ctx context.Context, state *settingsstate.State) error {
|
||||
log := log.With(zap.String("spaceId", d.spaceId))
|
||||
d.deletionState.Add(state.DeletedIds)
|
||||
if state.DeleterId == "" {
|
||||
return nil
|
||||
}
|
||||
// we should delete space
|
||||
log.Debug("deleting space")
|
||||
if d.isResponsible {
|
||||
mapIds := map[string]struct{}{}
|
||||
for _, id := range d.provider.AllIds() {
|
||||
if id != d.settingsId {
|
||||
mapIds[id] = struct{}{}
|
||||
}
|
||||
}
|
||||
d.deletionState.Add(mapIds)
|
||||
}
|
||||
d.onSpaceDelete()
|
||||
return nil
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
package settings
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anyproto/any-sync/commonspace/deletionstate/mock_deletionstate"
|
||||
"github.com/anyproto/any-sync/commonspace/object/treemanager/mock_treemanager"
|
||||
"github.com/anyproto/any-sync/commonspace/settings/mock_settings"
|
||||
"github.com/anyproto/any-sync/commonspace/settings/settingsstate"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDeletionManager_UpdateState_NotResponsible(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
ctx := context.Background()
|
||||
|
||||
spaceId := "spaceId"
|
||||
settingsId := "settingsId"
|
||||
state := &settingsstate.State{
|
||||
DeletedIds: map[string]struct{}{"id": {}},
|
||||
DeleterId: "deleterId",
|
||||
}
|
||||
deleted := false
|
||||
onDeleted := func() {
|
||||
deleted = true
|
||||
}
|
||||
delState := mock_deletionstate.NewMockObjectDeletionState(ctrl)
|
||||
treeManager := mock_treemanager.NewMockTreeManager(ctrl)
|
||||
|
||||
delState.EXPECT().Add(state.DeletedIds)
|
||||
|
||||
delManager := newDeletionManager(spaceId,
|
||||
settingsId,
|
||||
false,
|
||||
treeManager,
|
||||
delState,
|
||||
nil,
|
||||
onDeleted)
|
||||
err := delManager.UpdateState(ctx, state)
|
||||
require.NoError(t, err)
|
||||
require.True(t, deleted)
|
||||
}
|
||||
|
||||
func TestDeletionManager_UpdateState_Responsible(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
ctx := context.Background()
|
||||
|
||||
spaceId := "spaceId"
|
||||
settingsId := "settingsId"
|
||||
state := &settingsstate.State{
|
||||
DeletedIds: map[string]struct{}{"id": struct{}{}},
|
||||
DeleterId: "deleterId",
|
||||
}
|
||||
deleted := false
|
||||
onDeleted := func() {
|
||||
deleted = true
|
||||
}
|
||||
delState := mock_deletionstate.NewMockObjectDeletionState(ctrl)
|
||||
treeManager := mock_treemanager.NewMockTreeManager(ctrl)
|
||||
provider := mock_settings.NewMockSpaceIdsProvider(ctrl)
|
||||
|
||||
delState.EXPECT().Add(state.DeletedIds)
|
||||
provider.EXPECT().AllIds().Return([]string{"id", "otherId", settingsId})
|
||||
delState.EXPECT().Add(map[string]struct{}{"id": {}, "otherId": {}})
|
||||
delManager := newDeletionManager(spaceId,
|
||||
settingsId,
|
||||
true,
|
||||
treeManager,
|
||||
delState,
|
||||
provider,
|
||||
onDeleted)
|
||||
|
||||
err := delManager.UpdateState(ctx, state)
|
||||
require.NoError(t, err)
|
||||
require.True(t, deleted)
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/anyproto/any-sync/commonspace/settings (interfaces: DeletionManager,Deleter,SpaceIdsProvider)
|
||||
|
||||
// Package mock_settings is a generated GoMock package.
|
||||
package mock_settings
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
settingsstate "github.com/anyproto/any-sync/commonspace/settings/settingsstate"
|
||||
gomock "go.uber.org/mock/gomock"
|
||||
)
|
||||
|
||||
// MockDeletionManager is a mock of DeletionManager interface.
|
||||
type MockDeletionManager struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockDeletionManagerMockRecorder
|
||||
}
|
||||
|
||||
// MockDeletionManagerMockRecorder is the mock recorder for MockDeletionManager.
|
||||
type MockDeletionManagerMockRecorder struct {
|
||||
mock *MockDeletionManager
|
||||
}
|
||||
|
||||
// NewMockDeletionManager creates a new mock instance.
|
||||
func NewMockDeletionManager(ctrl *gomock.Controller) *MockDeletionManager {
|
||||
mock := &MockDeletionManager{ctrl: ctrl}
|
||||
mock.recorder = &MockDeletionManagerMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockDeletionManager) EXPECT() *MockDeletionManagerMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// UpdateState mocks base method.
|
||||
func (m *MockDeletionManager) UpdateState(arg0 context.Context, arg1 *settingsstate.State) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UpdateState", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// UpdateState indicates an expected call of UpdateState.
|
||||
func (mr *MockDeletionManagerMockRecorder) UpdateState(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateState", reflect.TypeOf((*MockDeletionManager)(nil).UpdateState), arg0, arg1)
|
||||
}
|
||||
|
||||
// MockDeleter is a mock of Deleter interface.
|
||||
type MockDeleter struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockDeleterMockRecorder
|
||||
}
|
||||
|
||||
// MockDeleterMockRecorder is the mock recorder for MockDeleter.
|
||||
type MockDeleterMockRecorder struct {
|
||||
mock *MockDeleter
|
||||
}
|
||||
|
||||
// NewMockDeleter creates a new mock instance.
|
||||
func NewMockDeleter(ctrl *gomock.Controller) *MockDeleter {
|
||||
mock := &MockDeleter{ctrl: ctrl}
|
||||
mock.recorder = &MockDeleterMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockDeleter) EXPECT() *MockDeleterMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// Delete mocks base method.
|
||||
func (m *MockDeleter) Delete() {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Delete")
|
||||
}
|
||||
|
||||
// Delete indicates an expected call of Delete.
|
||||
func (mr *MockDeleterMockRecorder) Delete() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockDeleter)(nil).Delete))
|
||||
}
|
||||
|
||||
// MockSpaceIdsProvider is a mock of SpaceIdsProvider interface.
|
||||
type MockSpaceIdsProvider struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockSpaceIdsProviderMockRecorder
|
||||
}
|
||||
|
||||
// MockSpaceIdsProviderMockRecorder is the mock recorder for MockSpaceIdsProvider.
|
||||
type MockSpaceIdsProviderMockRecorder struct {
|
||||
mock *MockSpaceIdsProvider
|
||||
}
|
||||
|
||||
// NewMockSpaceIdsProvider creates a new mock instance.
|
||||
func NewMockSpaceIdsProvider(ctrl *gomock.Controller) *MockSpaceIdsProvider {
|
||||
mock := &MockSpaceIdsProvider{ctrl: ctrl}
|
||||
mock.recorder = &MockSpaceIdsProviderMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use.
|
||||
func (m *MockSpaceIdsProvider) EXPECT() *MockSpaceIdsProviderMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// AllIds mocks base method.
|
||||
func (m *MockSpaceIdsProvider) AllIds() []string {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AllIds")
|
||||
ret0, _ := ret[0].([]string)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// AllIds indicates an expected call of AllIds.
|
||||
func (mr *MockSpaceIdsProviderMockRecorder) AllIds() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AllIds", reflect.TypeOf((*MockSpaceIdsProvider)(nil).AllIds))
|
||||
}
|
|
@ -2,17 +2,14 @@ package settings
|
|||
|
||||
import (
|
||||
"context"
|
||||
"github.com/anyproto/any-sync/commonspace/deletionmanager"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/anyproto/any-sync/accountservice"
|
||||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/anyproto/any-sync/commonspace/deletionstate"
|
||||
"github.com/anyproto/any-sync/commonspace/headsync"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/synctree"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
|
||||
"github.com/anyproto/any-sync/commonspace/object/treemanager"
|
||||
"github.com/anyproto/any-sync/commonspace/objecttreebuilder"
|
||||
"github.com/anyproto/any-sync/commonspace/spacestate"
|
||||
"github.com/anyproto/any-sync/commonspace/spacestorage"
|
||||
|
@ -24,8 +21,6 @@ const CName = "common.commonspace.settings"
|
|||
|
||||
type Settings interface {
|
||||
DeleteTree(ctx context.Context, id string) (err error)
|
||||
SpaceDeleteRawChange(ctx context.Context) (raw *treechangeproto.RawTreeChangeWithId, err error)
|
||||
DeleteSpace(ctx context.Context, deleteChange *treechangeproto.RawTreeChangeWithId) (err error)
|
||||
SettingsObject() SettingsObject
|
||||
app.ComponentRunnable
|
||||
}
|
||||
|
@ -36,11 +31,8 @@ func New() Settings {
|
|||
|
||||
type settings struct {
|
||||
account accountservice.Service
|
||||
treeManager treemanager.TreeManager
|
||||
storage spacestorage.SpaceStorage
|
||||
configuration nodeconf.NodeConf
|
||||
deletionState deletionstate.ObjectDeletionState
|
||||
headsync headsync.HeadSync
|
||||
treeBuilder objecttreebuilder.TreeBuilderComponent
|
||||
spaceIsDeleted *atomic.Bool
|
||||
|
||||
|
@ -49,12 +41,8 @@ type settings struct {
|
|||
|
||||
func (s *settings) Init(a *app.App) (err error) {
|
||||
s.account = a.MustComponent(accountservice.CName).(accountservice.Service)
|
||||
s.treeManager = app.MustComponent[treemanager.TreeManager](a)
|
||||
s.headsync = a.MustComponent(headsync.CName).(headsync.HeadSync)
|
||||
s.configuration = a.MustComponent(nodeconf.CName).(nodeconf.NodeConf)
|
||||
s.deletionState = a.MustComponent(deletionstate.CName).(deletionstate.ObjectDeletionState)
|
||||
s.treeBuilder = a.MustComponent(objecttreebuilder.CName).(objecttreebuilder.TreeBuilderComponent)
|
||||
|
||||
sharedState := a.MustComponent(spacestate.CName).(*spacestate.SpaceState)
|
||||
s.storage = a.MustComponent(spacestorage.CName).(spacestorage.SpaceStorage)
|
||||
s.spaceIsDeleted = sharedState.SpaceIsDeleted
|
||||
|
@ -74,12 +62,9 @@ func (s *settings) Init(a *app.App) (err error) {
|
|||
return
|
||||
},
|
||||
Account: s.account,
|
||||
TreeManager: s.treeManager,
|
||||
Store: s.storage,
|
||||
Configuration: s.configuration,
|
||||
DeletionState: s.deletionState,
|
||||
Provider: s.headsync,
|
||||
OnSpaceDelete: s.onSpaceDelete,
|
||||
DelManager: a.MustComponent(deletionmanager.CName).(deletionmanager.DeletionManager),
|
||||
}
|
||||
s.settingsObject = NewSettingsObject(deps, sharedState.SpaceId)
|
||||
return nil
|
||||
|
@ -101,22 +86,6 @@ func (s *settings) DeleteTree(ctx context.Context, id string) (err error) {
|
|||
return s.settingsObject.DeleteObject(id)
|
||||
}
|
||||
|
||||
func (s *settings) SpaceDeleteRawChange(ctx context.Context) (raw *treechangeproto.RawTreeChangeWithId, err error) {
|
||||
return s.settingsObject.SpaceDeleteRawChange()
|
||||
}
|
||||
|
||||
func (s *settings) DeleteSpace(ctx context.Context, deleteChange *treechangeproto.RawTreeChangeWithId) (err error) {
|
||||
return s.settingsObject.DeleteSpace(ctx, deleteChange)
|
||||
}
|
||||
|
||||
func (s *settings) onSpaceDelete() {
|
||||
err := s.storage.SetSpaceDeleted()
|
||||
if err != nil {
|
||||
log.Warn("failed to set space deleted")
|
||||
}
|
||||
s.spaceIsDeleted.Swap(true)
|
||||
}
|
||||
|
||||
func (s *settings) SettingsObject() SettingsObject {
|
||||
return s.settingsObject
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
//go:generate mockgen -destination mock_settings/mock_settings.go github.com/anyproto/any-sync/commonspace/settings DeletionManager,Deleter,SpaceIdsProvider
|
||||
package settings
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/anyproto/any-sync/commonspace/deletionstate"
|
||||
"github.com/anyproto/any-sync/commonspace/deletionmanager"
|
||||
"github.com/anyproto/any-sync/util/crypto"
|
||||
|
||||
"github.com/anyproto/any-sync/accountservice"
|
||||
|
@ -21,7 +20,6 @@ import (
|
|||
"github.com/anyproto/any-sync/nodeconf"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
var log = logger.NewNamed("common.commonspace.settings")
|
||||
|
@ -30,8 +28,6 @@ type SettingsObject interface {
|
|||
synctree.SyncTree
|
||||
Init(ctx context.Context) (err error)
|
||||
DeleteObject(id string) (err error)
|
||||
DeleteSpace(ctx context.Context, raw *treechangeproto.RawTreeChangeWithId) (err error)
|
||||
SpaceDeleteRawChange() (raw *treechangeproto.RawTreeChangeWithId, err error)
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -60,56 +56,30 @@ type Deps struct {
|
|||
TreeManager treemanager.TreeManager
|
||||
Store spacestorage.SpaceStorage
|
||||
Configuration nodeconf.NodeConf
|
||||
DeletionState deletionstate.ObjectDeletionState
|
||||
Provider SpaceIdsProvider
|
||||
OnSpaceDelete func()
|
||||
DelManager deletionmanager.DeletionManager
|
||||
// testing dependencies
|
||||
builder settingsstate.StateBuilder
|
||||
del Deleter
|
||||
delManager DeletionManager
|
||||
changeFactory settingsstate.ChangeFactory
|
||||
}
|
||||
|
||||
type settingsObject struct {
|
||||
synctree.SyncTree
|
||||
account accountservice.Service
|
||||
spaceId string
|
||||
treeManager treemanager.TreeManager
|
||||
store spacestorage.SpaceStorage
|
||||
builder settingsstate.StateBuilder
|
||||
buildFunc BuildTreeFunc
|
||||
loop *deleteLoop
|
||||
account accountservice.Service
|
||||
spaceId string
|
||||
store spacestorage.SpaceStorage
|
||||
builder settingsstate.StateBuilder
|
||||
buildFunc BuildTreeFunc
|
||||
|
||||
state *settingsstate.State
|
||||
deletionState deletionstate.ObjectDeletionState
|
||||
deletionManager DeletionManager
|
||||
deletionManager deletionmanager.DeletionManager
|
||||
changeFactory settingsstate.ChangeFactory
|
||||
}
|
||||
|
||||
func NewSettingsObject(deps Deps, spaceId string) (obj SettingsObject) {
|
||||
var (
|
||||
deleter Deleter
|
||||
deletionManager DeletionManager
|
||||
builder settingsstate.StateBuilder
|
||||
changeFactory settingsstate.ChangeFactory
|
||||
builder settingsstate.StateBuilder
|
||||
changeFactory settingsstate.ChangeFactory
|
||||
)
|
||||
if deps.del == nil {
|
||||
deleter = newDeleter(deps.Store, deps.DeletionState, deps.TreeManager)
|
||||
} else {
|
||||
deleter = deps.del
|
||||
}
|
||||
if deps.delManager == nil {
|
||||
deletionManager = newDeletionManager(
|
||||
spaceId,
|
||||
deps.Store.SpaceSettingsId(),
|
||||
deps.Configuration.IsResponsible(spaceId),
|
||||
deps.TreeManager,
|
||||
deps.DeletionState,
|
||||
deps.Provider,
|
||||
deps.OnSpaceDelete)
|
||||
} else {
|
||||
deletionManager = deps.delManager
|
||||
}
|
||||
if deps.builder == nil {
|
||||
builder = settingsstate.NewStateBuilder()
|
||||
} else {
|
||||
|
@ -121,23 +91,13 @@ func NewSettingsObject(deps Deps, spaceId string) (obj SettingsObject) {
|
|||
changeFactory = deps.changeFactory
|
||||
}
|
||||
|
||||
loop := newDeleteLoop(func() {
|
||||
deleter.Delete()
|
||||
})
|
||||
deps.DeletionState.AddObserver(func(ids []string) {
|
||||
loop.notify()
|
||||
})
|
||||
|
||||
s := &settingsObject{
|
||||
loop: loop,
|
||||
spaceId: spaceId,
|
||||
account: deps.Account,
|
||||
deletionState: deps.DeletionState,
|
||||
treeManager: deps.TreeManager,
|
||||
store: deps.Store,
|
||||
buildFunc: deps.BuildFunc,
|
||||
builder: builder,
|
||||
deletionManager: deletionManager,
|
||||
deletionManager: deps.DelManager,
|
||||
changeFactory: changeFactory,
|
||||
}
|
||||
obj = s
|
||||
|
@ -151,7 +111,6 @@ func (s *settingsObject) updateIds(tr objecttree.ObjectTree) {
|
|||
log.Error("failed to build state", zap.Error(err))
|
||||
return
|
||||
}
|
||||
log.Debug("updating object state", zap.String("deleted by", s.state.DeleterId))
|
||||
if err = s.deletionManager.UpdateState(context.Background(), s.state); err != nil {
|
||||
log.Error("failed to update state", zap.Error(err))
|
||||
}
|
||||
|
@ -180,7 +139,6 @@ func (s *settingsObject) Init(ctx context.Context) (err error) {
|
|||
if err = s.checkHistoryState(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
s.loop.Run()
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -207,48 +165,9 @@ func (s *settingsObject) checkHistoryState(ctx context.Context) (err error) {
|
|||
}
|
||||
|
||||
func (s *settingsObject) Close() error {
|
||||
s.loop.Close()
|
||||
return s.SyncTree.Close()
|
||||
}
|
||||
|
||||
func (s *settingsObject) DeleteSpace(ctx context.Context, raw *treechangeproto.RawTreeChangeWithId) (err error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
defer func() {
|
||||
log.Debug("finished adding delete change", zap.Error(err))
|
||||
}()
|
||||
err = s.verifyDeleteSpace(raw)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
res, err := s.AddRawChanges(ctx, objecttree.RawChangesPayload{
|
||||
NewHeads: []string{raw.Id},
|
||||
RawChanges: []*treechangeproto.RawTreeChangeWithId{raw},
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if !slices.Contains(res.Heads, raw.Id) {
|
||||
err = ErrCantDeleteSpace
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *settingsObject) SpaceDeleteRawChange() (raw *treechangeproto.RawTreeChangeWithId, err error) {
|
||||
accountData := s.account.Account()
|
||||
data, err := s.changeFactory.CreateSpaceDeleteChange(accountData.PeerId, s.state, false)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return s.PrepareChange(objecttree.SignableChangeContent{
|
||||
Data: data,
|
||||
Key: accountData.SignKey,
|
||||
IsSnapshot: false,
|
||||
IsEncrypted: false,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *settingsObject) DeleteObject(id string) (err error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
|
|
@ -3,16 +3,14 @@ package settings
|
|||
import (
|
||||
"context"
|
||||
"github.com/anyproto/any-sync/accountservice/mock_accountservice"
|
||||
"github.com/anyproto/any-sync/commonspace/deletionstate/mock_deletionstate"
|
||||
"github.com/anyproto/any-sync/commonspace/deletionmanager/mock_deletionmanager"
|
||||
"github.com/anyproto/any-sync/commonspace/object/accountdata"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/synctree"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/synctree/mock_synctree"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/synctree/updatelistener"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
|
||||
"github.com/anyproto/any-sync/commonspace/object/treemanager/mock_treemanager"
|
||||
"github.com/anyproto/any-sync/commonspace/settings/mock_settings"
|
||||
"github.com/anyproto/any-sync/commonspace/settings/settingsstate"
|
||||
"github.com/anyproto/any-sync/commonspace/settings/settingsstate/mock_settingsstate"
|
||||
"github.com/anyproto/any-sync/commonspace/spacestorage/mock_spacestorage"
|
||||
|
@ -50,12 +48,10 @@ type settingsFixture struct {
|
|||
treeManager *mock_treemanager.MockTreeManager
|
||||
spaceStorage *mock_spacestorage.MockSpaceStorage
|
||||
stateBuilder *mock_settingsstate.MockStateBuilder
|
||||
deletionManager *mock_settings.MockDeletionManager
|
||||
deletionManager *mock_deletionmanager.MockDeletionManager
|
||||
changeFactory *mock_settingsstate.MockChangeFactory
|
||||
deleter *mock_settings.MockDeleter
|
||||
syncTree *mock_synctree.MockSyncTree
|
||||
historyTree *mock_objecttree.MockObjectTree
|
||||
delState *mock_deletionstate.MockObjectDeletionState
|
||||
account *mock_accountservice.MockService
|
||||
}
|
||||
|
||||
|
@ -67,15 +63,11 @@ func newSettingsFixture(t *testing.T) *settingsFixture {
|
|||
acc := mock_accountservice.NewMockService(ctrl)
|
||||
treeManager := mock_treemanager.NewMockTreeManager(ctrl)
|
||||
st := mock_spacestorage.NewMockSpaceStorage(ctrl)
|
||||
delState := mock_deletionstate.NewMockObjectDeletionState(ctrl)
|
||||
delManager := mock_settings.NewMockDeletionManager(ctrl)
|
||||
delManager := mock_deletionmanager.NewMockDeletionManager(ctrl)
|
||||
stateBuilder := mock_settingsstate.NewMockStateBuilder(ctrl)
|
||||
changeFactory := mock_settingsstate.NewMockChangeFactory(ctrl)
|
||||
syncTree := mock_synctree.NewMockSyncTree(ctrl)
|
||||
historyTree := mock_objecttree.NewMockObjectTree(ctrl)
|
||||
del := mock_settings.NewMockDeleter(ctrl)
|
||||
|
||||
delState.EXPECT().AddObserver(gomock.Any())
|
||||
|
||||
buildFunc := BuildTreeFunc(func(ctx context.Context, id string, listener updatelistener.UpdateListener) (synctree.SyncTree, error) {
|
||||
require.Equal(t, objectId, id)
|
||||
|
@ -90,11 +82,9 @@ func newSettingsFixture(t *testing.T) *settingsFixture {
|
|||
Account: acc,
|
||||
TreeManager: treeManager,
|
||||
Store: st,
|
||||
DeletionState: delState,
|
||||
delManager: delManager,
|
||||
DelManager: delManager,
|
||||
changeFactory: changeFactory,
|
||||
builder: stateBuilder,
|
||||
del: del,
|
||||
}
|
||||
doc := NewSettingsObject(deps, spaceId).(*settingsObject)
|
||||
return &settingsFixture{
|
||||
|
@ -107,17 +97,14 @@ func newSettingsFixture(t *testing.T) *settingsFixture {
|
|||
stateBuilder: stateBuilder,
|
||||
changeFactory: changeFactory,
|
||||
deletionManager: delManager,
|
||||
deleter: del,
|
||||
syncTree: syncTree,
|
||||
account: acc,
|
||||
delState: delState,
|
||||
historyTree: historyTree,
|
||||
}
|
||||
}
|
||||
|
||||
func (fx *settingsFixture) init(t *testing.T) {
|
||||
fx.spaceStorage.EXPECT().SpaceSettingsId().Return(fx.docId)
|
||||
fx.deleter.EXPECT().Delete()
|
||||
fx.stateBuilder.EXPECT().Build(fx.historyTree, nil).Return(&settingsstate.State{}, nil)
|
||||
fx.doc.state = &settingsstate.State{}
|
||||
|
||||
|
@ -235,64 +222,3 @@ func TestSettingsObject_Update(t *testing.T) {
|
|||
|
||||
fx.doc.Update(fx.doc)
|
||||
}
|
||||
|
||||
func TestSettingsObject_DeleteSpace(t *testing.T) {
|
||||
fx := newSettingsFixture(t)
|
||||
defer fx.stop(t)
|
||||
|
||||
fx.init(t)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
deleterId := "delId"
|
||||
rawCh := &treechangeproto.RawTreeChangeWithId{
|
||||
RawChange: []byte{1},
|
||||
Id: "id",
|
||||
}
|
||||
changeFactory := settingsstate.NewChangeFactory()
|
||||
delChange, _ := changeFactory.CreateSpaceDeleteChange(deleterId, &settingsstate.State{}, false)
|
||||
|
||||
fx.syncTree.EXPECT().UnpackChange(rawCh).Return(delChange, nil)
|
||||
fx.syncTree.EXPECT().AddRawChanges(gomock.Any(), objecttree.RawChangesPayload{
|
||||
NewHeads: []string{rawCh.Id},
|
||||
RawChanges: []*treechangeproto.RawTreeChangeWithId{rawCh},
|
||||
}).Return(objecttree.AddResult{
|
||||
Heads: []string{rawCh.Id},
|
||||
}, nil)
|
||||
|
||||
err := fx.doc.DeleteSpace(context.Background(), rawCh)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestSettingsObject_DeleteSpaceIncorrectChange(t *testing.T) {
|
||||
fx := newSettingsFixture(t)
|
||||
defer fx.stop(t)
|
||||
|
||||
fx.init(t)
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
t.Run("incorrect change type", func(t *testing.T) {
|
||||
rawCh := &treechangeproto.RawTreeChangeWithId{
|
||||
RawChange: []byte{1},
|
||||
Id: "id",
|
||||
}
|
||||
changeFactory := settingsstate.NewChangeFactory()
|
||||
delChange, _ := changeFactory.CreateObjectDeleteChange("otherId", &settingsstate.State{}, false)
|
||||
|
||||
fx.syncTree.EXPECT().UnpackChange(rawCh).Return(delChange, nil)
|
||||
err := fx.doc.DeleteSpace(context.Background(), rawCh)
|
||||
require.NotNil(t, err)
|
||||
})
|
||||
|
||||
t.Run("empty peer", func(t *testing.T) {
|
||||
rawCh := &treechangeproto.RawTreeChangeWithId{
|
||||
RawChange: []byte{1},
|
||||
Id: "id",
|
||||
}
|
||||
changeFactory := settingsstate.NewChangeFactory()
|
||||
delChange, _ := changeFactory.CreateSpaceDeleteChange("", &settingsstate.State{}, false)
|
||||
|
||||
fx.syncTree.EXPECT().UnpackChange(rawCh).Return(delChange, nil)
|
||||
err := fx.doc.DeleteSpace(context.Background(), rawCh)
|
||||
require.NotNil(t, err)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
type ChangeFactory interface {
|
||||
CreateObjectDeleteChange(id string, state *State, isSnapshot bool) (res []byte, err error)
|
||||
CreateSpaceDeleteChange(peerId string, state *State, isSnapshot bool) (res []byte, err error)
|
||||
}
|
||||
|
||||
func NewChangeFactory() ChangeFactory {
|
||||
|
@ -26,44 +25,23 @@ func (c *changeFactory) CreateObjectDeleteChange(id string, state *State, isSnap
|
|||
},
|
||||
}
|
||||
if isSnapshot {
|
||||
change.Snapshot = c.makeSnapshot(state, id, "")
|
||||
change.Snapshot = c.makeSnapshot(state, id)
|
||||
}
|
||||
res, err = change.Marshal()
|
||||
return
|
||||
}
|
||||
|
||||
func (c *changeFactory) CreateSpaceDeleteChange(peerId string, state *State, isSnapshot bool) (res []byte, err error) {
|
||||
content := &spacesyncproto.SpaceSettingsContent_SpaceDelete{
|
||||
SpaceDelete: &spacesyncproto.SpaceDelete{DeleterPeerId: peerId},
|
||||
}
|
||||
change := &spacesyncproto.SettingsData{
|
||||
Content: []*spacesyncproto.SpaceSettingsContent{
|
||||
{Value: content},
|
||||
},
|
||||
}
|
||||
if isSnapshot {
|
||||
change.Snapshot = c.makeSnapshot(state, "", peerId)
|
||||
}
|
||||
res, err = change.Marshal()
|
||||
return
|
||||
}
|
||||
|
||||
func (c *changeFactory) makeSnapshot(state *State, objectId, deleterPeer string) *spacesyncproto.SpaceSettingsSnapshot {
|
||||
func (c *changeFactory) makeSnapshot(state *State, objectId string) *spacesyncproto.SpaceSettingsSnapshot {
|
||||
var (
|
||||
deletedIds = make([]string, 0, len(state.DeletedIds)+1)
|
||||
deleterId = state.DeleterId
|
||||
)
|
||||
if objectId != "" {
|
||||
deletedIds = append(deletedIds, objectId)
|
||||
}
|
||||
if deleterPeer != "" {
|
||||
deleterId = deleterPeer
|
||||
}
|
||||
for id := range state.DeletedIds {
|
||||
deletedIds = append(deletedIds, id)
|
||||
}
|
||||
return &spacesyncproto.SpaceSettingsSnapshot{
|
||||
DeletedIds: deletedIds,
|
||||
DeleterPeerId: deleterId,
|
||||
DeletedIds: deletedIds,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ func TestChangeFactory_CreateObjectDeleteChange(t *testing.T) {
|
|||
factory := NewChangeFactory()
|
||||
state := &State{
|
||||
DeletedIds: map[string]struct{}{"1": {}, "2": {}},
|
||||
DeleterId: "del",
|
||||
}
|
||||
marshalled, err := factory.CreateObjectDeleteChange("3", state, false)
|
||||
require.NoError(t, err)
|
||||
|
@ -29,34 +28,7 @@ func TestChangeFactory_CreateObjectDeleteChange(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
slices.Sort(data.Snapshot.DeletedIds)
|
||||
require.Equal(t, &spacesyncproto.SpaceSettingsSnapshot{
|
||||
DeletedIds: []string{"1", "2", "3"},
|
||||
DeleterPeerId: "del",
|
||||
DeletedIds: []string{"1", "2", "3"},
|
||||
}, data.Snapshot)
|
||||
require.Equal(t, "3", data.Content[0].Value.(*spacesyncproto.SpaceSettingsContent_ObjectDelete).ObjectDelete.Id)
|
||||
}
|
||||
|
||||
func TestChangeFactory_CreateSpaceDeleteChange(t *testing.T) {
|
||||
factory := NewChangeFactory()
|
||||
state := &State{
|
||||
DeletedIds: map[string]struct{}{"1": {}, "2": {}},
|
||||
}
|
||||
marshalled, err := factory.CreateSpaceDeleteChange("del", state, false)
|
||||
require.NoError(t, err)
|
||||
data := &spacesyncproto.SettingsData{}
|
||||
err = proto.Unmarshal(marshalled, data)
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, data.Snapshot)
|
||||
require.Equal(t, "del", data.Content[0].Value.(*spacesyncproto.SpaceSettingsContent_SpaceDelete).SpaceDelete.DeleterPeerId)
|
||||
|
||||
marshalled, err = factory.CreateSpaceDeleteChange("del", state, true)
|
||||
require.NoError(t, err)
|
||||
data = &spacesyncproto.SettingsData{}
|
||||
err = proto.Unmarshal(marshalled, data)
|
||||
require.NoError(t, err)
|
||||
slices.Sort(data.Snapshot.DeletedIds)
|
||||
require.Equal(t, &spacesyncproto.SpaceSettingsSnapshot{
|
||||
DeletedIds: []string{"1", "2"},
|
||||
DeleterPeerId: "del",
|
||||
}, data.Snapshot)
|
||||
require.Equal(t, "del", data.Content[0].Value.(*spacesyncproto.SpaceSettingsContent_SpaceDelete).SpaceDelete.DeleterPeerId)
|
||||
}
|
||||
|
|
|
@ -87,18 +87,3 @@ func (mr *MockChangeFactoryMockRecorder) CreateObjectDeleteChange(arg0, arg1, ar
|
|||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateObjectDeleteChange", reflect.TypeOf((*MockChangeFactory)(nil).CreateObjectDeleteChange), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// CreateSpaceDeleteChange mocks base method.
|
||||
func (m *MockChangeFactory) CreateSpaceDeleteChange(arg0 string, arg1 *settingsstate.State, arg2 bool) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CreateSpaceDeleteChange", arg0, arg1, arg2)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// CreateSpaceDeleteChange indicates an expected call of CreateSpaceDeleteChange.
|
||||
func (mr *MockChangeFactoryMockRecorder) CreateSpaceDeleteChange(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateSpaceDeleteChange", reflect.TypeOf((*MockChangeFactory)(nil).CreateSpaceDeleteChange), arg0, arg1, arg2)
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import "github.com/anyproto/any-sync/commonspace/spacesyncproto"
|
|||
|
||||
type State struct {
|
||||
DeletedIds map[string]struct{}
|
||||
DeleterId string
|
||||
LastIteratedId string
|
||||
}
|
||||
|
||||
|
@ -18,7 +17,6 @@ func NewStateFromSnapshot(snapshot *spacesyncproto.SpaceSettingsSnapshot, lastIt
|
|||
for _, id := range snapshot.DeletedIds {
|
||||
st.DeletedIds[id] = struct{}{}
|
||||
}
|
||||
st.DeleterId = snapshot.DeleterPeerId
|
||||
st.LastIteratedId = lastIteratedId
|
||||
return st
|
||||
}
|
||||
|
|
|
@ -64,8 +64,6 @@ func (s *stateBuilder) processChange(change *objecttree.Change, rootId string, s
|
|||
switch {
|
||||
case cnt.GetObjectDelete() != nil:
|
||||
state.DeletedIds[cnt.GetObjectDelete().GetId()] = struct{}{}
|
||||
case cnt.GetSpaceDelete() != nil:
|
||||
state.DeleterId = cnt.GetSpaceDelete().GetDeleterPeerId()
|
||||
}
|
||||
}
|
||||
return state
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package settingsstate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/anyproto/any-sync/commonspace/object/accountdata"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree/mock_objecttree"
|
||||
"github.com/anyproto/any-sync/commonspace/spacesyncproto"
|
||||
|
@ -22,6 +24,26 @@ func TestStateBuilder_ProcessChange(t *testing.T) {
|
|||
require.Equal(t, map[string]struct{}{deletedId: struct{}{}}, newSt.DeletedIds)
|
||||
})
|
||||
|
||||
t.Run("correct space deleted", func(t *testing.T) {
|
||||
keys, _ := accountdata.NewRandom()
|
||||
ch := &objecttree.Change{
|
||||
Identity: keys.SignKey.GetPublic(),
|
||||
}
|
||||
ch.PreviousIds = []string{"someId"}
|
||||
ch.Model = &spacesyncproto.SettingsData{
|
||||
Content: []*spacesyncproto.SpaceSettingsContent{
|
||||
{Value: &spacesyncproto.SpaceSettingsContent_SpaceDelete{
|
||||
SpaceDelete: &spacesyncproto.SpaceDelete{DeleterPeerId: "peerId"},
|
||||
}},
|
||||
},
|
||||
}
|
||||
ch.Id = "someId"
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
newSt := sb.processChange(ch, rootId, NewState())
|
||||
fmt.Println(newSt)
|
||||
})
|
||||
|
||||
t.Run("changeId is equal to startId, LastIteratedId is equal to startId", func(t *testing.T) {
|
||||
ch := &objecttree.Change{}
|
||||
ch.Model = &spacesyncproto.SettingsData{
|
||||
|
@ -45,14 +67,12 @@ func TestStateBuilder_ProcessChange(t *testing.T) {
|
|||
ch.PreviousIds = []string{"someId"}
|
||||
ch.Model = &spacesyncproto.SettingsData{
|
||||
Snapshot: &spacesyncproto.SpaceSettingsSnapshot{
|
||||
DeletedIds: []string{"id1", "id2"},
|
||||
DeleterPeerId: "peerId",
|
||||
DeletedIds: []string{"id1", "id2"},
|
||||
},
|
||||
}
|
||||
ch.Id = "rootId"
|
||||
newSt := sb.processChange(ch, rootId, NewState())
|
||||
require.Equal(t, map[string]struct{}{"id1": struct{}{}, "id2": struct{}{}}, newSt.DeletedIds)
|
||||
require.Equal(t, "peerId", newSt.DeleterId)
|
||||
})
|
||||
|
||||
t.Run("changeId is not equal to lastIteratedId or rootId", func(t *testing.T) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue