mirror of
https://github.com/anyproto/anytype-heart.git
synced 2025-06-07 21:37:04 +09:00
Implement personal space deletion
This commit is contained in:
parent
b66ddadf14
commit
47cf57b4e2
6 changed files with 206 additions and 57 deletions
|
@ -26,7 +26,7 @@ func (s *service) initMarketplaceSpace(ctx context.Context) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *service) initTechSpace(ctx context.Context) (err error) {
|
||||
func (s *service) createTechSpace(ctx context.Context) (err error) {
|
||||
if s.techSpace, err = s.factory.CreateAndSetTechSpace(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -34,9 +34,10 @@ func (s *service) initTechSpace(ctx context.Context) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (s *service) initPersonalSpace(ctx context.Context) (err error) {
|
||||
if s.newAccount {
|
||||
return s.createPersonalSpace(ctx)
|
||||
func (s *service) loadTechSpace(ctx context.Context) (err error) {
|
||||
if s.techSpace, err = s.factory.LoadAndSetTechSpace(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return s.loadPersonalSpace(ctx)
|
||||
close(s.techSpaceReady)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -2,29 +2,47 @@ package personalspace
|
|||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/anyproto/any-sync/app/logger"
|
||||
"go.uber.org/multierr"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/anyproto/anytype-heart/space/internal/components/spacestatus"
|
||||
"github.com/anyproto/anytype-heart/space/internal/spacecontroller"
|
||||
"github.com/anyproto/anytype-heart/space/internal/spaceprocess/initial"
|
||||
"github.com/anyproto/anytype-heart/space/internal/spaceprocess/loader"
|
||||
"github.com/anyproto/anytype-heart/space/internal/spaceprocess/mode"
|
||||
"github.com/anyproto/anytype-heart/space/internal/spaceprocess/offloader"
|
||||
"github.com/anyproto/anytype-heart/space/spacecore"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/space/techspace"
|
||||
)
|
||||
|
||||
func NewSpaceController(spaceId string, metadata []byte, a *app.App) spacecontroller.SpaceController {
|
||||
var log = logger.NewNamed("common.space.personalspace")
|
||||
|
||||
func NewSpaceController(spaceId string, metadata []byte, a *app.App) (spacecontroller.SpaceController, error) {
|
||||
techSpace := a.MustComponent(techspace.CName).(techspace.TechSpace)
|
||||
spaceCore := a.MustComponent(spacecore.CName).(spacecore.SpaceCoreService)
|
||||
return &spaceController{
|
||||
app: a,
|
||||
newApp, err := makeStatusApp(a, spaceId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := &spaceController{
|
||||
app: newApp,
|
||||
spaceId: spaceId,
|
||||
techSpace: techSpace,
|
||||
status: newApp.MustComponent(spacestatus.CName).(spacestatus.SpaceStatus),
|
||||
spaceCore: spaceCore,
|
||||
metadata: metadata,
|
||||
}
|
||||
sm, err := mode.NewStateMachine(s, log.With(zap.String("spaceId", s.spaceId)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.sm = sm
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func makeStatusApp(a *app.App, spaceId string) (*app.App, error) {
|
||||
|
@ -38,45 +56,53 @@ func makeStatusApp(a *app.App, spaceId string) (*app.App, error) {
|
|||
}
|
||||
|
||||
type spaceController struct {
|
||||
app *app.App
|
||||
spaceId string
|
||||
metadata []byte
|
||||
app *app.App
|
||||
spaceId string
|
||||
metadata []byte
|
||||
lastUpdatedStatus spaceinfo.AccountStatus
|
||||
|
||||
loader loader.Loader
|
||||
spaceCore spacecore.SpaceCoreService
|
||||
techSpace techspace.TechSpace
|
||||
status spacestatus.SpaceStatus
|
||||
|
||||
sm *mode.StateMachine
|
||||
mx sync.Mutex
|
||||
}
|
||||
|
||||
func (s *spaceController) Start(ctx context.Context) (err error) {
|
||||
// Check that space exists. If not, probably user is migrating from legacy version
|
||||
_, err = s.spaceCore.Get(ctx, s.spaceId)
|
||||
if err != nil {
|
||||
return
|
||||
switch s.status.GetPersistentStatus() {
|
||||
case spaceinfo.AccountStatusDeleted:
|
||||
_, err := s.sm.ChangeMode(mode.ModeOffloading)
|
||||
return err
|
||||
default:
|
||||
_, err := s.sm.ChangeMode(mode.ModeLoading)
|
||||
return err
|
||||
}
|
||||
exists, err := s.techSpace.SpaceViewExists(ctx, s.spaceId)
|
||||
// This could happen for old accounts
|
||||
if !exists || err != nil {
|
||||
info := spaceinfo.NewSpacePersistentInfo(s.spaceId)
|
||||
info.SetAccountStatus(spaceinfo.AccountStatusUnknown)
|
||||
err = s.techSpace.SpaceViewCreate(ctx, s.spaceId, false, info)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
func (s *spaceController) Process(md mode.Mode) mode.Process {
|
||||
switch md {
|
||||
case mode.ModeInitial:
|
||||
return initial.New()
|
||||
case mode.ModeOffloading:
|
||||
return offloader.New(s.app)
|
||||
default:
|
||||
return &personalLoader{
|
||||
spaceId: s.spaceId,
|
||||
spaceCore: s.spaceCore,
|
||||
techSpace: s.techSpace,
|
||||
newLoader: s.newLoader,
|
||||
}
|
||||
}
|
||||
s.app, err = makeStatusApp(s.app, s.spaceId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
s.loader = s.newLoader()
|
||||
return s.loader.Start(ctx)
|
||||
}
|
||||
|
||||
func (s *spaceController) Mode() mode.Mode {
|
||||
return mode.ModeLoading
|
||||
return s.sm.GetMode()
|
||||
}
|
||||
|
||||
func (s *spaceController) Current() any {
|
||||
return s.loader
|
||||
return s.sm.GetProcess()
|
||||
}
|
||||
|
||||
func (s *spaceController) SpaceId() string {
|
||||
|
@ -92,18 +118,45 @@ func (s *spaceController) newLoader() loader.Loader {
|
|||
}
|
||||
|
||||
func (s *spaceController) Update() error {
|
||||
// TODO: [PS] Implement for deletion
|
||||
return nil
|
||||
s.mx.Lock()
|
||||
status := s.status.GetPersistentStatus()
|
||||
if s.lastUpdatedStatus == status {
|
||||
s.mx.Unlock()
|
||||
return nil
|
||||
}
|
||||
s.lastUpdatedStatus = status
|
||||
s.mx.Unlock()
|
||||
updateStatus := func(mode mode.Mode) error {
|
||||
_, err := s.sm.ChangeMode(mode)
|
||||
return err
|
||||
}
|
||||
switch status {
|
||||
case spaceinfo.AccountStatusDeleted:
|
||||
return updateStatus(mode.ModeOffloading)
|
||||
default:
|
||||
return updateStatus(mode.ModeLoading)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *spaceController) SetPersistentInfo(ctx context.Context, info spaceinfo.SpacePersistentInfo) error {
|
||||
// TODO: [PS] Implement for deletion
|
||||
return nil
|
||||
err := s.status.SetPersistentInfo(info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.Update()
|
||||
}
|
||||
|
||||
func (s *spaceController) SetLocalInfo(ctx context.Context, info spaceinfo.SpaceLocalInfo) error {
|
||||
// TODO: [PS] Implement for deletion
|
||||
return nil
|
||||
return s.status.SetLocalInfo(info)
|
||||
}
|
||||
|
||||
func (s *spaceController) Delete(ctx context.Context) error {
|
||||
offloading, err := s.sm.ChangeMode(mode.ModeOffloading)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
of := offloading.(offloader.Offloader)
|
||||
return of.WaitOffload(ctx)
|
||||
}
|
||||
|
||||
func (s *spaceController) Close(ctx context.Context) error {
|
||||
|
@ -116,9 +169,9 @@ func (s *spaceController) Close(ctx context.Context) error {
|
|||
}
|
||||
|
||||
func (s *spaceController) GetStatus() spaceinfo.AccountStatus {
|
||||
return spaceinfo.AccountStatusUnknown
|
||||
return s.status.GetPersistentStatus()
|
||||
}
|
||||
|
||||
func (s *spaceController) GetLocalStatus() spaceinfo.LocalStatus {
|
||||
return spaceinfo.LocalStatusOk
|
||||
return s.status.GetLocalStatus()
|
||||
}
|
||||
|
|
37
space/internal/personalspace/personalloader.go
Normal file
37
space/internal/personalspace/personalloader.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
package personalspace
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/anyproto/anytype-heart/space/internal/spaceprocess/loader"
|
||||
"github.com/anyproto/anytype-heart/space/spacecore"
|
||||
"github.com/anyproto/anytype-heart/space/spaceinfo"
|
||||
"github.com/anyproto/anytype-heart/space/techspace"
|
||||
)
|
||||
|
||||
type personalLoader struct {
|
||||
loader.Loader
|
||||
spaceId string
|
||||
spaceCore spacecore.SpaceCoreService
|
||||
techSpace techspace.TechSpace
|
||||
newLoader func() loader.Loader
|
||||
}
|
||||
|
||||
func (p *personalLoader) Start(ctx context.Context) (err error) {
|
||||
_, err = p.spaceCore.Get(ctx, p.spaceId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
exists, err := p.techSpace.SpaceViewExists(ctx, p.spaceId)
|
||||
// This could happen for old accounts
|
||||
if !exists || err != nil {
|
||||
info := spaceinfo.NewSpacePersistentInfo(p.spaceId)
|
||||
info.SetAccountStatus(spaceinfo.AccountStatusUnknown)
|
||||
err = p.techSpace.SpaceViewCreate(ctx, p.spaceId, false, info)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
p.Loader = p.newLoader()
|
||||
return p.Loader.Start(ctx)
|
||||
}
|
|
@ -12,6 +12,8 @@ import (
|
|||
"github.com/anyproto/any-sync/accountservice"
|
||||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/anyproto/any-sync/app/logger"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treechangeproto"
|
||||
"github.com/anyproto/any-sync/commonspace/spacesyncproto"
|
||||
"github.com/anyproto/any-sync/util/crypto"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"go.uber.org/zap"
|
||||
|
@ -179,9 +181,27 @@ func (s *service) initAccount(ctx context.Context) (err error) {
|
|||
if err != nil {
|
||||
return fmt.Errorf("init marketplace space: %w", err)
|
||||
}
|
||||
err = s.initTechSpace(ctx)
|
||||
err = s.loadTechSpace(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("init tech space: %w", err)
|
||||
if errors.Is(err, spacesyncproto.ErrSpaceMissing) {
|
||||
// check if we have a personal space
|
||||
_, persErr := s.spaceCore.Get(ctx, s.personalSpaceId)
|
||||
if persErr != nil {
|
||||
// then probably we just didn't have anything
|
||||
return fmt.Errorf("init tech space: %w", err)
|
||||
}
|
||||
// this is an old account
|
||||
err = s.createTechSpace(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("init tech space: %w", err)
|
||||
}
|
||||
err = s.loadPersonalSpace(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("init personal space: %w", err)
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("init tech space: %w", err)
|
||||
}
|
||||
}
|
||||
s.techSpace.WakeUpViews()
|
||||
// only persist networkId after successful space init
|
||||
|
@ -197,22 +217,22 @@ func (s *service) createAccount(ctx context.Context) (err error) {
|
|||
if err != nil {
|
||||
return fmt.Errorf("init marketplace space: %w", err)
|
||||
}
|
||||
err = s.initTechSpace(ctx)
|
||||
err = s.createTechSpace(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("init tech space: %w", err)
|
||||
}
|
||||
// err = s.initPersonalSpace(ctx)
|
||||
// if err != nil {
|
||||
// if errors.Is(err, spacesyncproto.ErrSpaceMissing) || errors.Is(err, treechangeproto.ErrGetTree) {
|
||||
// err = ErrSpaceNotExists
|
||||
// }
|
||||
// // fix for the users that have wrong network id stored in the folder
|
||||
// err2 := s.config.ResetStoredNetworkId()
|
||||
// if err2 != nil {
|
||||
// log.Error("reset network id", zap.Error(err2))
|
||||
// }
|
||||
// return fmt.Errorf("init personal space: %w", err)
|
||||
// }
|
||||
err = s.createPersonalSpace(ctx)
|
||||
if err != nil {
|
||||
if errors.Is(err, spacesyncproto.ErrSpaceMissing) || errors.Is(err, treechangeproto.ErrGetTree) {
|
||||
err = ErrSpaceNotExists
|
||||
}
|
||||
// fix for the users that have wrong network id stored in the folder
|
||||
err2 := s.config.ResetStoredNetworkId()
|
||||
if err2 != nil {
|
||||
log.Error("reset network id", zap.Error(err2))
|
||||
}
|
||||
return fmt.Errorf("init personal space: %w", err)
|
||||
}
|
||||
s.techSpace.WakeUpViews()
|
||||
// only persist networkId after successful space init
|
||||
err = s.config.PersistAccountNetworkId()
|
||||
|
|
|
@ -65,7 +65,7 @@ func TestService_Init(t *testing.T) {
|
|||
defer ctxCancel2()
|
||||
|
||||
factory.EXPECT().CreateAndSetTechSpace(ctx2).Return(&clientspace.TechSpace{}, nil)
|
||||
require.NoError(t, serv.initTechSpace(ctx2))
|
||||
require.NoError(t, serv.loadTechSpace(ctx2))
|
||||
|
||||
s, err := serv.Get(ctx2, serv.techSpaceId)
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -29,6 +29,7 @@ type SpaceFactory interface {
|
|||
NewShareableSpace(ctx context.Context, id string, info spaceinfo.SpacePersistentInfo) (spacecontroller.SpaceController, error)
|
||||
CreateMarketplaceSpace(ctx context.Context) (sp spacecontroller.SpaceController, err error)
|
||||
CreateAndSetTechSpace(ctx context.Context) (*clientspace.TechSpace, error)
|
||||
LoadAndSetTechSpace(ctx context.Context) (*clientspace.TechSpace, error)
|
||||
CreateInvitingSpace(ctx context.Context, id, aclHeadId string) (sp spacecontroller.SpaceController, err error)
|
||||
}
|
||||
|
||||
|
@ -82,7 +83,10 @@ func (s *spaceFactory) CreatePersonalSpace(ctx context.Context, metadata []byte)
|
|||
}
|
||||
return nil, err
|
||||
}
|
||||
ctrl := personalspace.NewSpaceController(coreSpace.Id(), metadata, s.app)
|
||||
ctrl, err := personalspace.NewSpaceController(coreSpace.Id(), metadata, s.app)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = ctrl.Start(ctx)
|
||||
return ctrl, err
|
||||
}
|
||||
|
@ -92,7 +96,10 @@ func (s *spaceFactory) NewPersonalSpace(ctx context.Context, metadata []byte) (c
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ctrl = personalspace.NewSpaceController(coreSpace.Id(), metadata, s.app)
|
||||
ctrl, err = personalspace.NewSpaceController(coreSpace.Id(), metadata, s.app)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = ctrl.Start(ctx)
|
||||
return ctrl, err
|
||||
}
|
||||
|
@ -124,6 +131,37 @@ func (s *spaceFactory) CreateAndSetTechSpace(ctx context.Context) (*clientspace.
|
|||
return ts, nil
|
||||
}
|
||||
|
||||
func (s *spaceFactory) LoadAndSetTechSpace(ctx context.Context) (*clientspace.TechSpace, error) {
|
||||
techSpace := techspace.New()
|
||||
id, err := s.spaceCore.DeriveID(ctx, spacecore.TechSpaceType)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("derive tech space id: %w", err)
|
||||
}
|
||||
techCoreSpace, err := s.spaceCore.Get(ctx, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("derive tech space: %w", err)
|
||||
}
|
||||
deps := clientspace.TechSpaceDeps{
|
||||
CommonSpace: techCoreSpace,
|
||||
ObjectFactory: s.objectFactory,
|
||||
AccountService: s.accountService,
|
||||
PersonalSpaceId: s.personalSpaceId,
|
||||
Indexer: s.indexer,
|
||||
Installer: s.installer,
|
||||
TechSpace: techSpace,
|
||||
}
|
||||
ts := clientspace.NewTechSpace(deps)
|
||||
s.techSpace = ts
|
||||
s.app = s.app.ChildApp()
|
||||
s.app.Register(s.techSpace)
|
||||
err = ts.Run(techCoreSpace, ts.Cache)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("run tech space: %w", err)
|
||||
}
|
||||
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
func (s *spaceFactory) NewShareableSpace(ctx context.Context, id string, info spaceinfo.SpacePersistentInfo) (spacecontroller.SpaceController, error) {
|
||||
ctrl, err := shareablespace.NewSpaceController(id, info, s.app)
|
||||
if err != nil {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue