1
0
Fork 0
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:
mcrakhman 2024-09-23 21:43:08 +02:00
parent b66ddadf14
commit 47cf57b4e2
No known key found for this signature in database
GPG key ID: DED12CFEF5B8396B
6 changed files with 206 additions and 57 deletions

View file

@ -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
}

View file

@ -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()
}

View 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)
}

View file

@ -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()

View file

@ -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)

View file

@ -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 {