Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GO-2827 Unbind user files (reclaim / reconcile space usage) #1226

Merged
merged 18 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .mockery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ packages:
github.com/anyproto/anytype-heart/core/filestorage/filesync:
interfaces:
FileSync:
github.com/anyproto/anytype-heart/core/filestorage/rpcstore:
interfaces:
Service:
RpcStore:
github.com/anyproto/anytype-heart/core/block/import/common/objectid:
interfaces:
IdGetterProvider:
Expand Down Expand Up @@ -165,6 +169,9 @@ packages:
github.com/anyproto/anytype-heart/core/block/object/idresolver:
interfaces:
Resolver:
github.com/anyproto/anytype-heart/core/filestorage:
interfaces:
FileStorage:
github.com/anyproto/anytype-heart/util/linkpreview:
interfaces:
LinkPreview:
646 changes: 323 additions & 323 deletions clientlibrary/service/service.pb.go

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions core/anytype/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import (
"github.com/anyproto/anytype-heart/core/files/fileacl"
"github.com/anyproto/anytype-heart/core/files/fileobject"
"github.com/anyproto/anytype-heart/core/files/fileuploader"
"github.com/anyproto/anytype-heart/core/files/reconciler"
"github.com/anyproto/anytype-heart/core/filestorage"
"github.com/anyproto/anytype-heart/core/filestorage/filesync"
"github.com/anyproto/anytype-heart/core/filestorage/rpcstore"
Expand Down Expand Up @@ -241,6 +242,7 @@ func Bootstrap(a *app.App, components ...app.Component) {
Register(deletioncontroller.New()).
Register(invitestore.New()).
Register(filesync.New()).
Register(reconciler.New()).
Register(fileobject.New(200*time.Millisecond, 2*time.Second)).
Register(inviteservice.New()).
Register(acl.New()).
Expand Down
8 changes: 3 additions & 5 deletions core/block/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"context"
"fmt"

"go.uber.org/zap"

Check failure on line 7 in core/block/delete.go

View workflow job for this annotation

GitHub Actions / unit-test

"go.uber.org/zap" imported and not used

Check failure on line 7 in core/block/delete.go

View workflow job for this annotation

GitHub Actions / unit-test

"go.uber.org/zap" imported and not used

Check failure on line 7 in core/block/delete.go

View workflow job for this annotation

GitHub Actions / lint

"go.uber.org/zap" imported and not used

Check failure on line 7 in core/block/delete.go

View workflow job for this annotation

GitHub Actions / lint

"go.uber.org/zap" imported and not used

Check failure on line 7 in core/block/delete.go

View workflow job for this annotation

GitHub Actions / lint

"go.uber.org/zap" imported and not used

"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
"github.com/anyproto/anytype-heart/core/domain"
Expand Down Expand Up @@ -52,7 +52,7 @@
}
err = s.OnDelete(id, nil)
if err != nil {
return fmt.Errorf("on delete: %w", err)

Check failure on line 55 in core/block/delete.go

View workflow job for this annotation

GitHub Actions / unit-test

missing return

Check failure on line 55 in core/block/delete.go

View workflow job for this annotation

GitHub Actions / unit-test

missing return

Check failure on line 55 in core/block/delete.go

View workflow job for this annotation

GitHub Actions / lint

missing return (typecheck)

Check failure on line 55 in core/block/delete.go

View workflow job for this annotation

GitHub Actions / lint

missing return) (typecheck)

Check failure on line 55 in core/block/delete.go

View workflow job for this annotation

GitHub Actions / lint

missing return) (typecheck)
}
if sbType == coresb.SmartBlockTypeRelation {
err := s.deleteRelationOptions(relationKey)
Expand All @@ -67,11 +67,9 @@
if err != nil {
return fmt.Errorf("delete file data: %w", err)
}
// this will call DeleteTree asynchronously in the end
return spc.DeleteTree(context.Background(), id.ObjectID)
err = spc.DeleteTree(context.Background(), id.ObjectID)
default:
// this will call DeleteTree asynchronously in the end
return spc.DeleteTree(context.Background(), id.ObjectID)
err = spc.DeleteTree(context.Background(), id.ObjectID)
}
if err != nil {
return
Expand Down Expand Up @@ -137,7 +135,7 @@
return nil
})
if err != nil {
log.Error("failed to perform delete operation on object", zap.Error(err))
log.With("error", err, "objectId", id.ObjectID).Error("failed to perform delete operation on object")
}
if err := s.objectStore.DeleteObject(id); err != nil {
return fmt.Errorf("delete object from local store: %w", err)
Expand Down
3 changes: 3 additions & 0 deletions core/block/editor/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/anyproto/anytype-heart/core/files"
"github.com/anyproto/anytype-heart/core/files/fileobject"
"github.com/anyproto/anytype-heart/core/files/fileuploader"
"github.com/anyproto/anytype-heart/core/files/reconciler"
"github.com/anyproto/anytype-heart/pkg/lib/core"
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/filestore"
Expand Down Expand Up @@ -58,6 +59,7 @@ type ObjectFactory struct {
fileObjectService fileobject.Service
processService process.Service
fileUploaderService fileuploader.Service
fileReconciler reconciler.Reconciler
objectDeleter ObjectDeleter
}

Expand Down Expand Up @@ -85,6 +87,7 @@ func (f *ObjectFactory) Init(a *app.App) (err error) {
f.processService = app.MustComponent[process.Service](a)
f.fileUploaderService = app.MustComponent[fileuploader.Service](a)
f.objectDeleter = app.MustComponent[ObjectDeleter](a)
f.fileReconciler = app.MustComponent[reconciler.Reconciler](a)
return nil
}

Expand Down
14 changes: 10 additions & 4 deletions core/block/editor/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,20 @@ import (
"github.com/anyproto/anytype-heart/core/block/source"
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/core/files/fileobject"
"github.com/anyproto/anytype-heart/core/files/reconciler"
"github.com/anyproto/anytype-heart/core/filestorage"
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
)

func (f *ObjectFactory) newFile(sb smartblock.SmartBlock) *File {
basicComponent := basic.NewBasic(sb, f.objectStore, f.layoutConverter)
return &File{
SmartBlock: sb,
ChangeReceiver: sb.(source.ChangeReceiver),
AllOperations: basicComponent,
Text: stext.NewText(sb, f.objectStore, f.eventSender), fileObjectService: f.fileObjectService,
SmartBlock: sb,
ChangeReceiver: sb.(source.ChangeReceiver),
AllOperations: basicComponent,
Text: stext.NewText(sb, f.objectStore, f.eventSender),
fileObjectService: f.fileObjectService,
reconciler: f.fileReconciler,
}
}

Expand All @@ -32,6 +35,7 @@ type File struct {
basic.AllOperations
stext.Text
fileObjectService fileobject.Service
reconciler reconciler.Reconciler
}

func (f *File) CreationStateMigration(ctx *smartblock.InitContext) migration.Migration {
Expand Down Expand Up @@ -70,6 +74,8 @@ func (f *File) Init(ctx *smartblock.InitContext) error {
return err
}

f.SmartBlock.AddHook(f.reconciler.FileObjectHook(domain.FullID{SpaceID: f.SpaceID(), ObjectID: f.Id()}), smartblock.HookBeforeApply)

if !ctx.IsNewObject {
err = f.fileObjectService.EnsureFileAddedToSyncQueue(domain.FullID{ObjectID: f.Id(), SpaceID: f.SpaceID()}, ctx.State.Details())
if err != nil {
Expand Down
7 changes: 3 additions & 4 deletions core/block/editor/smartblock/smartblock.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ type ApplyFlag int
var (
ErrSimpleBlockNotFound = errors.New("simple block not found")
ErrCantInitExistingSmartblockWithNonEmptyState = errors.New("can't init existing smartblock with non-empty state")
ErrIsDeleted = errors.New("smartblock is deleted")
)

const (
Expand Down Expand Up @@ -550,7 +549,7 @@ func (sb *smartBlock) EnabledRelationAsDependentObjects() {
func (sb *smartBlock) Apply(s *state.State, flags ...ApplyFlag) (err error) {
startTime := time.Now()
if sb.IsDeleted() {
return ErrIsDeleted
return domain.ErrObjectIsDeleted
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider refactoring the Apply method to improve readability and maintainability.

The Apply method is quite lengthy and handles multiple responsibilities. It would be beneficial to break this method into smaller, more focused methods. This can improve readability, make the code easier to maintain, and simplify unit testing.

}
var (
sendEvent = true
Expand Down Expand Up @@ -968,7 +967,7 @@ func (sb *smartBlock) RemoveExtraRelations(ctx session.Context, relationIds []st

func (sb *smartBlock) StateAppend(f func(d state.Doc) (s *state.State, changes []*pb.ChangeContent, err error)) error {
if sb.IsDeleted() {
return ErrIsDeleted
return domain.ErrObjectIsDeleted
}
s, changes, err := f(sb.Doc)
if err != nil {
Expand Down Expand Up @@ -1001,7 +1000,7 @@ func (sb *smartBlock) StateAppend(f func(d state.Doc) (s *state.State, changes [
// TODO: need to test StateRebuild
func (sb *smartBlock) StateRebuild(d state.Doc) (err error) {
if sb.IsDeleted() {
return ErrIsDeleted
return domain.ErrObjectIsDeleted
}
sb.updateRestrictions()
sb.injectDerivedDetails(d.(*state.State), sb.SpaceID(), sb.Type())
Expand Down
1 change: 1 addition & 0 deletions core/domain/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ package domain
import "errors"

var ErrValidationFailed = errors.New("validation failed")
var ErrObjectIsDeleted = errors.New("object is deleted")
14 changes: 14 additions & 0 deletions core/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/anyproto/anytype-heart/core/domain/objectorigin"
"github.com/anyproto/anytype-heart/core/files"
"github.com/anyproto/anytype-heart/core/files/fileobject"
"github.com/anyproto/anytype-heart/core/files/reconciler"
"github.com/anyproto/anytype-heart/pb"
)

Expand Down Expand Up @@ -194,3 +195,16 @@ func (mw *Middleware) FileNodeUsage(ctx context.Context, req *pb.RpcFileNodeUsag

return resp
}

func (mw *Middleware) FileReconcile(ctx context.Context, req *pb.RpcFileReconcileRequest) *pb.RpcFileReconcileResponse {
err := getService[reconciler.Reconciler](mw).Start(ctx)
if err != nil {
return &pb.RpcFileReconcileResponse{
Error: &pb.RpcFileReconcileResponseError{
Code: mapErrorCode[pb.RpcFileReconcileResponseErrorCode](err),
Description: err.Error(),
},
}
}
return &pb.RpcFileReconcileResponse{}
}
6 changes: 3 additions & 3 deletions core/files/files_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func TestFileAdd(t *testing.T) {
ctx := context.Background()

uploaded := make(chan struct{})
fx.fileSyncService.OnUploaded(func(objectId string) error {
fx.fileSyncService.OnUploaded(func(objectId string, fileId domain.FullFileId) error {
close(uploaded)
return nil
})
Expand Down Expand Up @@ -199,7 +199,7 @@ func TestFileAddWithCustomKeys(t *testing.T) {
ctx := context.Background()

uploaded := make(chan struct{})
fx.fileSyncService.OnUploaded(func(objectId string) error {
fx.fileSyncService.OnUploaded(func(objectId string, fileId domain.FullFileId) error {
close(uploaded)
return nil
})
Expand Down Expand Up @@ -237,7 +237,7 @@ func TestFileAddWithCustomKeys(t *testing.T) {
ctx := context.Background()

uploaded := make(chan struct{})
fx.fileSyncService.OnUploaded(func(objectId string) error {
fx.fileSyncService.OnUploaded(func(objectId string, fileId domain.FullFileId) error {
close(uploaded)
return nil
})
Expand Down
Loading
Loading