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-4444 Use bundle info to revise sys objects #1970

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ const MName = "ReadonlyRelationsFixer"
// This migration was implemented to fix relations in accounts of users that are not able to modify its value (GO-2331)
type Migration struct{}

func (Migration) Name() string {
func (m Migration) Name() string {
return MName
}

func (Migration) Run(ctx context.Context, log logger.CtxLogger, store, _ dependencies.QueryableStore, space dependencies.SpaceWithCtx) (toMigrate, migrated int, err error) {
func (m Migration) Run(ctx context.Context, log logger.CtxLogger, store dependencies.QueryableStore, space dependencies.SpaceWithCtx) (toMigrate, migrated int, err error) {
spaceId := space.Id()

relations, err := listReadonlyTagAndStatusRelations(store, spaceId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func TestFixReadonlyInRelations(t *testing.T) {
).Times(2)

// when
migrated, toMigrate, err := fixer.Run(ctx, log, store.SpaceIndex("space1"), nil, spc)
migrated, toMigrate, err := fixer.Run(ctx, log, store.SpaceIndex("space1"), spc)

// then
assert.NoError(t, err)
Expand All @@ -99,7 +99,7 @@ func TestFixReadonlyInRelations(t *testing.T) {
// sp.EXPECT().Do(mock.Anything, mock.Anything).Times(1).Return(nil)

// when
migrated, toMigrate, err := fixer.Run(ctx, log, store.SpaceIndex("space2"), nil, spc)
migrated, toMigrate, err := fixer.Run(ctx, log, store.SpaceIndex("space2"), spc)

// then
assert.NoError(t, err)
Expand All @@ -116,7 +116,7 @@ func TestFixReadonlyInRelations(t *testing.T) {
// sp.EXPECT().Do(mock.Anything, mock.Anything).Times(1).Return(nil)

// when
migrated, toMigrate, err := fixer.Run(ctx, log, store.SpaceIndex("space3"), nil, spc)
migrated, toMigrate, err := fixer.Run(ctx, log, store.SpaceIndex("space3"), spc)

// then
assert.NoError(t, err)
Expand Down
7 changes: 3 additions & 4 deletions space/internal/components/migration/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/anyproto/any-sync/app/logger"
"go.uber.org/zap"

"github.com/anyproto/anytype-heart/pkg/lib/localstore/addr"
"github.com/anyproto/anytype-heart/pkg/lib/localstore/objectstore"
"github.com/anyproto/anytype-heart/space/clientspace"
"github.com/anyproto/anytype-heart/space/internal/components/dependencies"
Expand All @@ -27,7 +26,7 @@ const (
var log = logger.NewNamed(CName)

type Migration interface {
Run(context.Context, logger.CtxLogger, dependencies.QueryableStore, dependencies.QueryableStore, dependencies.SpaceWithCtx) (toMigrate, migrated int, err error)
Run(context.Context, logger.CtxLogger, dependencies.QueryableStore, dependencies.SpaceWithCtx) (toMigrate, migrated int, err error)
Name() string
}

Expand Down Expand Up @@ -107,15 +106,15 @@ func (r *Runner) run(migrations ...Migration) (err error) {

start := time.Now()
store := r.store.SpaceIndex(spaceId)
marketPlaceStore := r.store.SpaceIndex(addr.AnytypeMarketplaceWorkspace)
// marketPlaceStore := r.store.SpaceIndex(addr.AnytypeMarketplaceWorkspace)
spent := time.Since(start)

for _, m := range migrations {
if e := r.ctx.Err(); e != nil {
err = errors.Join(err, e)
return
}
toMigrate, migrated, e := m.Run(r.ctx, log, store, marketPlaceStore, r.spc)
toMigrate, migrated, e := m.Run(r.ctx, log, store, r.spc)
if e != nil {
err = errors.Join(err, wrapError(e, m.Name(), spaceId, migrated, toMigrate))
continue
Expand Down
12 changes: 6 additions & 6 deletions space/internal/components/migration/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,11 @@ func TestRunner(t *testing.T) {

type longStoreMigration struct{}

func (longStoreMigration) Name() string {
func (m longStoreMigration) Name() string {
return "long migration"
}

func (longStoreMigration) Run(ctx context.Context, _ logger.CtxLogger, store, queryableStore dependencies.QueryableStore, _ dependencies.SpaceWithCtx) (toMigrate, migrated int, err error) {
func (m longStoreMigration) Run(ctx context.Context, _ logger.CtxLogger, store, queryableStore dependencies.QueryableStore, _ dependencies.SpaceWithCtx) (toMigrate, migrated int, err error) {
for {
if _, err = store.Query(database.Query{}); err != nil {
return 0, 0, err
Expand All @@ -154,11 +154,11 @@ func (longStoreMigration) Run(ctx context.Context, _ logger.CtxLogger, store, qu

type longSpaceMigration struct{}

func (longSpaceMigration) Name() string {
func (m longSpaceMigration) Name() string {
return "long migration"
}

func (longSpaceMigration) Run(ctx context.Context, _ logger.CtxLogger, _, store dependencies.QueryableStore, space dependencies.SpaceWithCtx) (toMigrate, migrated int, err error) {
func (m longSpaceMigration) Run(ctx context.Context, _ logger.CtxLogger, store dependencies.QueryableStore, space dependencies.SpaceWithCtx) (toMigrate, migrated int, err error) {
for {
if err = space.DoCtx(ctx, "", func(smartblock.SmartBlock) error {
// do smth
Expand All @@ -171,10 +171,10 @@ func (longSpaceMigration) Run(ctx context.Context, _ logger.CtxLogger, _, store

type instantMigration struct{}

func (instantMigration) Name() string {
func (m instantMigration) Name() string {
return "instant migration"
}

func (instantMigration) Run(context.Context, logger.CtxLogger, dependencies.QueryableStore, dependencies.QueryableStore, dependencies.SpaceWithCtx) (toMigrate, migrated int, err error) {
func (m instantMigration) Run(context.Context, logger.CtxLogger, dependencies.QueryableStore, dependencies.SpaceWithCtx) (toMigrate, migrated int, err error) {
return 0, 0, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
"github.com/anyproto/anytype-heart/core/domain"
"github.com/anyproto/anytype-heart/core/session"
"github.com/anyproto/anytype-heart/core/relationutils"
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
coresb "github.com/anyproto/anytype-heart/pkg/lib/core/smartblock"
"github.com/anyproto/anytype-heart/pkg/lib/database"
Expand All @@ -23,10 +23,6 @@ import (
"github.com/anyproto/anytype-heart/util/slice"
)

type detailsSettable interface {
SetDetails(ctx session.Context, details []*model.Detail, showEvent bool) (err error)
}

const MName = "SystemObjectReviser"

const revisionKey = bundle.RelationKeyRevision
Expand All @@ -37,23 +33,18 @@ const revisionKey = bundle.RelationKeyRevision
// For more info see 'System Objects Update' section of docs/Flow.md
type Migration struct{}

func (Migration) Name() string {
func (m Migration) Name() string {
return MName
}

func (Migration) Run(ctx context.Context, log logger.CtxLogger, store, marketPlace dependencies.QueryableStore, space dependencies.SpaceWithCtx) (toMigrate, migrated int, err error) {
func (m Migration) Run(ctx context.Context, log logger.CtxLogger, store dependencies.QueryableStore, space dependencies.SpaceWithCtx) (toMigrate, migrated int, err error) {
spaceObjects, err := listAllTypesAndRelations(store)
if err != nil {
return 0, 0, fmt.Errorf("failed to get relations and types from client space: %w", err)
}

marketObjects, err := listAllTypesAndRelations(marketPlace)
if err != nil {
return 0, 0, fmt.Errorf("failed to get relations from marketplace space: %w", err)
}

for _, details := range spaceObjects {
shouldBeRevised, e := reviseSystemObject(ctx, log, space, details, marketObjects)
shouldBeRevised, e := reviseObject(ctx, log, space, details)
if !shouldBeRevised {
continue
}
Expand Down Expand Up @@ -89,15 +80,25 @@ func listAllTypesAndRelations(store dependencies.QueryableStore) (map[string]*do
return details, nil
}

func reviseSystemObject(ctx context.Context, log logger.CtxLogger, space dependencies.SpaceWithCtx, localObject *domain.Details, marketObjects map[string]*domain.Details) (toRevise bool, err error) {
source := localObject.GetString(bundle.RelationKeySourceObject)
marketObject, found := marketObjects[source]
if !found || !isSystemObject(localObject) || marketObject.GetInt64(revisionKey) <= localObject.GetInt64(revisionKey) {
func reviseObject(ctx context.Context, log logger.CtxLogger, space dependencies.SpaceWithCtx, localObject *domain.Details) (toRevise bool, err error) {
uniqueKeyRaw := localObject.GetString(bundle.RelationKeyUniqueKey)

uk, err := domain.UnmarshalUniqueKey(uniqueKeyRaw)
if err != nil {
return false, fmt.Errorf("failed to unmarshal unique key '%s': %w", uniqueKeyRaw, err)
}

bundleObject := getBundleSystemObjectDetails(uk)
if bundleObject == nil {
return false, nil
}

if bundleObject.GetInt64(revisionKey) <= localObject.GetInt64(revisionKey) {
return false, nil
}
details := buildDiffDetails(marketObject, localObject)
details := buildDiffDetails(bundleObject, localObject)

recRelsDetail, err := checkRecommendedRelations(ctx, space, marketObject, localObject)
recRelsDetail, err := checkRecommendedRelations(ctx, space, bundleObject, localObject)
if err != nil {
log.Error("failed to check recommended relations", zap.Error(err))
}
Expand All @@ -107,33 +108,42 @@ func reviseSystemObject(ctx context.Context, log logger.CtxLogger, space depende
}

if details.Len() > 0 {
log.Debug("updating system object", zap.String("source", source), zap.String("space", space.Id()))
log.Debug("updating system object", zap.String("key", uk.InternalKey()), zap.String("space", space.Id()))
if err := space.DoCtx(ctx, localObject.GetString(bundle.RelationKeyId), func(sb smartblock.SmartBlock) error {
st := sb.NewState()
for key, value := range details.Iterate() {
st.SetDetail(key, value)
}
return sb.Apply(st)
}); err != nil {
return true, fmt.Errorf("failed to update system object %s in space %s: %w", source, space.Id(), err)
return true, fmt.Errorf("failed to update system object '%s' in space '%s': %w", uk.InternalKey(), space.Id(), err)
}
}
return true, nil
}

func isSystemObject(details *domain.Details) bool {
rawKey := details.GetString(bundle.RelationKeyUniqueKey)
uk, err := domain.UnmarshalUniqueKey(rawKey)
if err != nil {
return false
}
// getBundleSystemObjectDetails returns nil if the object with provided unique key is not either system relation or system type
func getBundleSystemObjectDetails(uk domain.UniqueKey) *domain.Details {
switch uk.SmartblockType() {
case coresb.SmartBlockTypeObjectType:
return lo.Contains(bundle.SystemTypes, domain.TypeKey(uk.InternalKey()))
typeKey := domain.TypeKey(uk.InternalKey())
if !lo.Contains(bundle.SystemTypes, typeKey) {
// non system object type, no need to revise
return nil
}
objectType := bundle.MustGetType(typeKey)
return (&relationutils.ObjectType{ObjectType: objectType}).BundledTypeDetails()
case coresb.SmartBlockTypeRelation:
return lo.Contains(bundle.SystemRelations, domain.RelationKey(uk.InternalKey()))
relationKey := domain.RelationKey(uk.InternalKey())
if !lo.Contains(bundle.SystemRelations, relationKey) {
// non system relation, no need to revise
return nil
}
relation := bundle.MustGetRelation(relationKey)
return (&relationutils.Relation{Relation: relation}).ToDetails()
default:
return nil
}
return false
}

func buildDiffDetails(origin, current *domain.Details) *domain.Details {
Expand Down
Loading
Loading