mirror of
https://github.com/anyproto/anytype-heart.git
synced 2025-06-10 18:10:49 +09:00
fix bugs
Signed-off-by: AnastasiaShemyakinskaya <shem98a@mail.ru>
This commit is contained in:
parent
dd3fb7ef93
commit
f34114b231
11 changed files with 128 additions and 96 deletions
|
@ -14,6 +14,7 @@ const (
|
|||
Syncing SpaceSyncStatus = 1
|
||||
Error SpaceSyncStatus = 2
|
||||
Offline SpaceSyncStatus = 3
|
||||
Unknown SpaceSyncStatus = 4
|
||||
)
|
||||
|
||||
type ObjectSyncStatus int32
|
||||
|
|
|
@ -15,7 +15,6 @@ import (
|
|||
"github.com/anyproto/anytype-heart/core/block/editor/basic"
|
||||
"github.com/anyproto/anytype-heart/core/block/editor/smartblock"
|
||||
"github.com/anyproto/anytype-heart/core/domain"
|
||||
"github.com/anyproto/anytype-heart/core/syncstatus/detailsupdater/helper"
|
||||
"github.com/anyproto/anytype-heart/core/syncstatus/filesyncstatus"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/bundle"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/database"
|
||||
|
@ -107,7 +106,7 @@ func (u *syncStatusUpdater) UpdateDetails(objectId []string, status domain.Objec
|
|||
}
|
||||
u.mx.Unlock()
|
||||
}
|
||||
err := u.batcher.TryAdd(&syncStatusDetails{
|
||||
err := u.batcher.Add(u.ctx, &syncStatusDetails{
|
||||
objectIds: objectId,
|
||||
status: status,
|
||||
syncError: syncError,
|
||||
|
@ -168,6 +167,9 @@ func (u *syncStatusUpdater) setObjectDetails(syncStatusDetails *syncStatusDetail
|
|||
if !changed {
|
||||
return nil
|
||||
}
|
||||
if !u.isLayoutSuitableForSyncRelations(record) {
|
||||
return nil
|
||||
}
|
||||
spc, err := u.spaceService.Get(u.ctx, syncStatusDetails.spaceId)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -196,6 +198,18 @@ func (u *syncStatusUpdater) setObjectDetails(syncStatusDetails *syncStatusDetail
|
|||
})
|
||||
}
|
||||
|
||||
func (u *syncStatusUpdater) isLayoutSuitableForSyncRelations(details *types.Struct) bool {
|
||||
layoutsWithoutSyncRelations := []float64{
|
||||
float64(model.ObjectType_participant),
|
||||
float64(model.ObjectType_dashboard),
|
||||
float64(model.ObjectType_spaceView),
|
||||
float64(model.ObjectType_space),
|
||||
float64(model.ObjectType_date),
|
||||
}
|
||||
layout := details.Fields[bundle.RelationKeyLayout.String()].GetNumberValue()
|
||||
return !slices.Contains(layoutsWithoutSyncRelations, layout)
|
||||
}
|
||||
|
||||
func mapObjectSyncToSpaceSyncStatus(status domain.ObjectSyncStatus, syncError domain.SyncError) domain.SpaceSyncStatus {
|
||||
switch status {
|
||||
case domain.ObjectSynced:
|
||||
|
@ -236,9 +250,6 @@ func mapFileStatus(status filesyncstatus.Status) (domain.ObjectSyncStatus, domai
|
|||
}
|
||||
|
||||
func (u *syncStatusUpdater) setSyncDetails(sb smartblock.SmartBlock, status domain.ObjectSyncStatus, syncError domain.SyncError) error {
|
||||
if !slices.Contains(helper.SyncRelationsSmartblockTypes(), sb.Type()) {
|
||||
return nil
|
||||
}
|
||||
if d, ok := sb.(basic.DetailsSettable); ok {
|
||||
syncStatusDetails := []*model.Detail{
|
||||
{
|
||||
|
@ -280,24 +291,29 @@ func (u *syncStatusUpdater) hasRelationsChange(record *types.Struct, status doma
|
|||
func (u *syncStatusUpdater) processEvents() {
|
||||
defer close(u.finish)
|
||||
for {
|
||||
status, err := u.batcher.WaitOne(u.ctx)
|
||||
if err != nil {
|
||||
statuses, err := u.batcher.Wait(u.ctx)
|
||||
if len(statuses) == 0 {
|
||||
return
|
||||
}
|
||||
for _, id := range status.objectIds {
|
||||
u.mx.Lock()
|
||||
objectStatus := u.entries[id]
|
||||
delete(u.entries, id)
|
||||
u.mx.Unlock()
|
||||
if objectStatus != nil {
|
||||
err := u.updateObjectDetails(objectStatus, id)
|
||||
if err != nil {
|
||||
log.Errorf("failed to update details %s", err)
|
||||
for _, status := range statuses {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, id := range status.objectIds {
|
||||
u.mx.Lock()
|
||||
objectStatus := u.entries[id]
|
||||
delete(u.entries, id)
|
||||
u.mx.Unlock()
|
||||
if objectStatus != nil {
|
||||
err := u.updateObjectDetails(objectStatus, id)
|
||||
if err != nil {
|
||||
log.Errorf("failed to update details %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(status.objectIds) == 0 {
|
||||
u.updateDetails(status)
|
||||
if len(status.objectIds) == 0 {
|
||||
u.updateDetails(status)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/anyproto/any-sync/app"
|
||||
"github.com/anyproto/any-sync/app/ocache"
|
||||
"github.com/cheggaaa/mb/v3"
|
||||
"github.com/gogo/protobuf/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
||||
|
@ -18,6 +19,7 @@ import (
|
|||
"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/localstore/objectstore"
|
||||
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
|
||||
"github.com/anyproto/anytype-heart/space/clientspace/mock_clientspace"
|
||||
"github.com/anyproto/anytype-heart/space/mock_space"
|
||||
"github.com/anyproto/anytype-heart/tests/testutil"
|
||||
|
@ -256,23 +258,33 @@ func TestSyncStatusUpdater_setSyncDetails(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestSyncStatusUpdater_updateDetails(t *testing.T) {
|
||||
t.Run("update sync status and date - no changes", func(t *testing.T) {
|
||||
func TestSyncStatusUpdater_isLayoutSuitableForSyncRelations(t *testing.T) {
|
||||
t.Run("isLayoutSuitableForSyncRelations - participant details", func(t *testing.T) {
|
||||
// given
|
||||
fixture := newFixture(t)
|
||||
space := mock_clientspace.NewMockSpace(t)
|
||||
fixture.service.EXPECT().Get(fixture.updater.ctx, "spaceId").Return(space, nil)
|
||||
fixture.storeFixture.AddObjects(t, []objectstore.TestObject{
|
||||
{
|
||||
bundle.RelationKeyId: pbtypes.String("id"),
|
||||
bundle.RelationKeySpaceId: pbtypes.String("spaceId"),
|
||||
},
|
||||
})
|
||||
space.EXPECT().DoLockedIfNotExists("id", mock.Anything).Return(nil)
|
||||
|
||||
// when
|
||||
fixture.statusUpdater.EXPECT().SendUpdate(domain.MakeSyncStatus("spaceId", domain.Synced, domain.Null, domain.Objects))
|
||||
fixture.updater.updateDetails(&syncStatusDetails{nil, domain.ObjectSynced, domain.Null, "spaceId"})
|
||||
details := &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_participant)),
|
||||
}}
|
||||
isSuitable := fixture.updater.isLayoutSuitableForSyncRelations(details)
|
||||
|
||||
// then
|
||||
assert.False(t, isSuitable)
|
||||
})
|
||||
|
||||
t.Run("isLayoutSuitableForSyncRelations - basic details", func(t *testing.T) {
|
||||
// given
|
||||
fixture := newFixture(t)
|
||||
|
||||
// when
|
||||
details := &types.Struct{Fields: map[string]*types.Value{
|
||||
bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_basic)),
|
||||
}}
|
||||
isSuitable := fixture.updater.isLayoutSuitableForSyncRelations(details)
|
||||
|
||||
// then
|
||||
assert.True(t, isSuitable)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,10 @@ func (f *FileState) SetSyncStatusAndErr(status domain.SpaceSyncStatus, syncErr d
|
|||
func (f *FileState) GetSyncStatus(spaceId string) domain.SpaceSyncStatus {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
return f.fileSyncStatusBySpace[spaceId]
|
||||
if status, ok := f.fileSyncStatusBySpace[spaceId]; ok {
|
||||
return status
|
||||
}
|
||||
return domain.Unknown
|
||||
}
|
||||
|
||||
func (f *FileState) GetSyncObjectCount(spaceId string) int {
|
||||
|
|
|
@ -56,7 +56,7 @@ func TestFileState_GetSyncStatus(t *testing.T) {
|
|||
syncStatus := fileState.GetSyncStatus("spaceId")
|
||||
|
||||
// then
|
||||
assert.Equal(t, domain.Synced, syncStatus)
|
||||
assert.Equal(t, domain.Unknown, syncStatus)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -158,51 +158,6 @@ func (_c *MockSpaceIdGetter_Name_Call) RunAndReturn(run func() string) *MockSpac
|
|||
return _c
|
||||
}
|
||||
|
||||
// PersonalSpaceId provides a mock function with given fields:
|
||||
func (_m *MockSpaceIdGetter) PersonalSpaceId() string {
|
||||
ret := _m.Called()
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for PersonalSpaceId")
|
||||
}
|
||||
|
||||
var r0 string
|
||||
if rf, ok := ret.Get(0).(func() string); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// MockSpaceIdGetter_PersonalSpaceId_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PersonalSpaceId'
|
||||
type MockSpaceIdGetter_PersonalSpaceId_Call struct {
|
||||
*mock.Call
|
||||
}
|
||||
|
||||
// PersonalSpaceId is a helper method to define mock.On call
|
||||
func (_e *MockSpaceIdGetter_Expecter) PersonalSpaceId() *MockSpaceIdGetter_PersonalSpaceId_Call {
|
||||
return &MockSpaceIdGetter_PersonalSpaceId_Call{Call: _e.mock.On("PersonalSpaceId")}
|
||||
}
|
||||
|
||||
func (_c *MockSpaceIdGetter_PersonalSpaceId_Call) Run(run func()) *MockSpaceIdGetter_PersonalSpaceId_Call {
|
||||
_c.Call.Run(func(args mock.Arguments) {
|
||||
run()
|
||||
})
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceIdGetter_PersonalSpaceId_Call) Return(_a0 string) *MockSpaceIdGetter_PersonalSpaceId_Call {
|
||||
_c.Call.Return(_a0)
|
||||
return _c
|
||||
}
|
||||
|
||||
func (_c *MockSpaceIdGetter_PersonalSpaceId_Call) RunAndReturn(run func() string) *MockSpaceIdGetter_PersonalSpaceId_Call {
|
||||
_c.Call.Return(run)
|
||||
return _c
|
||||
}
|
||||
|
||||
// TechSpaceId provides a mock function with given fields:
|
||||
func (_m *MockSpaceIdGetter) TechSpaceId() string {
|
||||
ret := _m.Called()
|
||||
|
|
|
@ -87,7 +87,10 @@ func (o *ObjectState) SetSyncStatusAndErr(status domain.SpaceSyncStatus, syncErr
|
|||
func (o *ObjectState) GetSyncStatus(spaceId string) domain.SpaceSyncStatus {
|
||||
o.Lock()
|
||||
defer o.Unlock()
|
||||
return o.objectSyncStatusBySpace[spaceId]
|
||||
if status, ok := o.objectSyncStatusBySpace[spaceId]; ok {
|
||||
return status
|
||||
}
|
||||
return domain.Unknown
|
||||
}
|
||||
|
||||
func (o *ObjectState) GetSyncObjectCount(spaceId string) int {
|
||||
|
|
|
@ -55,7 +55,7 @@ func TestObjectState_GetSyncStatus(t *testing.T) {
|
|||
syncStatus := objectState.GetSyncStatus("spaceId")
|
||||
|
||||
// then
|
||||
assert.Equal(t, domain.Synced, syncStatus)
|
||||
assert.Equal(t, domain.Unknown, syncStatus)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ type Updater interface {
|
|||
type SpaceIdGetter interface {
|
||||
app.Component
|
||||
TechSpaceId() string
|
||||
PersonalSpaceId() string
|
||||
AllSpaceIds() []string
|
||||
}
|
||||
|
||||
|
@ -89,7 +88,7 @@ func (s *spaceSyncStatus) Run(ctx context.Context) (err error) {
|
|||
close(s.finish)
|
||||
return
|
||||
} else {
|
||||
s.sendStartEvent(s.spaceIdGetter.PersonalSpaceId())
|
||||
s.sendStartEvent(s.spaceIdGetter.AllSpaceIds())
|
||||
}
|
||||
s.ctx, s.ctxCancel = context.WithCancel(context.Background())
|
||||
go s.processEvents()
|
||||
|
@ -106,14 +105,16 @@ func (s *spaceSyncStatus) sendEventToSession(spaceId, token string) {
|
|||
})
|
||||
}
|
||||
|
||||
func (s *spaceSyncStatus) sendStartEvent(spaceId string) {
|
||||
s.eventSender.Broadcast(&pb.Event{
|
||||
Messages: []*pb.EventMessage{{
|
||||
Value: &pb.EventMessageValueOfSpaceSyncStatusUpdate{
|
||||
SpaceSyncStatusUpdate: s.makeSpaceSyncEvent(spaceId),
|
||||
},
|
||||
}},
|
||||
})
|
||||
func (s *spaceSyncStatus) sendStartEvent(spaceIds []string) {
|
||||
for _, id := range spaceIds {
|
||||
s.eventSender.Broadcast(&pb.Event{
|
||||
Messages: []*pb.EventMessage{{
|
||||
Value: &pb.EventMessageValueOfSpaceSyncStatusUpdate{
|
||||
SpaceSyncStatusUpdate: s.makeSpaceSyncEvent(id),
|
||||
},
|
||||
}},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *spaceSyncStatus) sendLocalOnlyEvent() {
|
||||
|
@ -183,7 +184,11 @@ func (s *spaceSyncStatus) isStatusNotChanged(status *domain.SpaceSync) bool {
|
|||
return false
|
||||
}
|
||||
syncErrNotChanged := s.getError(status.SpaceId) == mapError(status.SyncError)
|
||||
statusNotChanged := s.getSpaceSyncStatus(status.SpaceId) == status.Status
|
||||
syncStatus := s.getSpaceSyncStatus(status.SpaceId)
|
||||
if syncStatus == domain.Unknown {
|
||||
return false
|
||||
}
|
||||
statusNotChanged := syncStatus == status.Status
|
||||
if syncErrNotChanged && statusNotChanged {
|
||||
return true
|
||||
}
|
||||
|
@ -221,6 +226,9 @@ func (s *spaceSyncStatus) getSpaceSyncStatus(spaceId string) domain.SpaceSyncSta
|
|||
filesStatus := s.filesState.GetSyncStatus(spaceId)
|
||||
objectsStatus := s.objectsState.GetSyncStatus(spaceId)
|
||||
|
||||
if s.isUnknown(filesStatus, objectsStatus) {
|
||||
return domain.Unknown
|
||||
}
|
||||
if s.isOfflineStatus(filesStatus, objectsStatus) {
|
||||
return domain.Offline
|
||||
}
|
||||
|
@ -276,6 +284,10 @@ func (s *spaceSyncStatus) getError(spaceId string) pb.EventSpaceSyncError {
|
|||
return pb.EventSpace_Null
|
||||
}
|
||||
|
||||
func (s *spaceSyncStatus) isUnknown(filesStatus domain.SpaceSyncStatus, objectsStatus domain.SpaceSyncStatus) bool {
|
||||
return filesStatus == domain.Unknown && objectsStatus == domain.Unknown
|
||||
}
|
||||
|
||||
func mapNetworkMode(mode pb.RpcAccountNetworkMode) pb.EventSpaceNetwork {
|
||||
switch mode {
|
||||
case pb.RpcAccount_LocalOnly:
|
||||
|
|
|
@ -42,7 +42,7 @@ func TestSpaceSyncStatus_Init(t *testing.T) {
|
|||
// then
|
||||
assert.Nil(t, err)
|
||||
|
||||
space.EXPECT().PersonalSpaceId().Return("personalId")
|
||||
space.EXPECT().AllSpaceIds().Return([]string{"personalId"})
|
||||
eventSender.EXPECT().Broadcast(&pb.Event{
|
||||
Messages: []*pb.EventMessage{{
|
||||
Value: &pb.EventMessageValueOfSpaceSyncStatusUpdate{
|
||||
|
@ -380,10 +380,38 @@ func TestSpaceSyncStatus_updateSpaceSyncStatus(t *testing.T) {
|
|||
// when
|
||||
assert.Equal(t, domain.Synced, status.objectsState.GetSyncStatus("spaceId"))
|
||||
assert.Equal(t, 0, status.objectsState.GetSyncObjectCount("spaceId"))
|
||||
assert.Equal(t, domain.Synced, status.filesState.GetSyncStatus("spaceId"))
|
||||
assert.Equal(t, domain.Unknown, status.filesState.GetSyncStatus("spaceId"))
|
||||
assert.Equal(t, 0, status.filesState.GetSyncObjectCount("spaceId"))
|
||||
assert.Equal(t, domain.Synced, status.getSpaceSyncStatus(syncStatus.SpaceId))
|
||||
})
|
||||
t.Run("send initial synced event", func(t *testing.T) {
|
||||
// given
|
||||
eventSender := mock_event.NewMockSender(t)
|
||||
status := spaceSyncStatus{
|
||||
eventSender: eventSender,
|
||||
networkConfig: &config.Config{NetworkMode: pb.RpcAccount_CustomConfig},
|
||||
batcher: mb.New[*domain.SpaceSync](0),
|
||||
filesState: NewFileState(objectstore.NewStoreFixture(t)),
|
||||
objectsState: NewObjectState(objectstore.NewStoreFixture(t)),
|
||||
}
|
||||
eventSender.EXPECT().Broadcast(&pb.Event{
|
||||
Messages: []*pb.EventMessage{{
|
||||
Value: &pb.EventMessageValueOfSpaceSyncStatusUpdate{
|
||||
SpaceSyncStatusUpdate: &pb.EventSpaceSyncStatusUpdate{
|
||||
Id: "spaceId",
|
||||
Status: pb.EventSpace_Synced,
|
||||
Network: pb.EventSpace_SelfHost,
|
||||
Error: pb.EventSpace_Null,
|
||||
SyncingObjectsCounter: 0,
|
||||
},
|
||||
},
|
||||
}},
|
||||
})
|
||||
// then
|
||||
syncStatus := domain.MakeSyncStatus("spaceId", domain.Synced, domain.Null, domain.Objects)
|
||||
status.updateSpaceSyncStatus(syncStatus)
|
||||
})
|
||||
|
||||
t.Run("not send not needed synced event", func(t *testing.T) {
|
||||
// given
|
||||
eventSender := mock_event.NewMockSender(t)
|
||||
|
@ -394,8 +422,10 @@ func TestSpaceSyncStatus_updateSpaceSyncStatus(t *testing.T) {
|
|||
filesState: NewFileState(objectstore.NewStoreFixture(t)),
|
||||
objectsState: NewObjectState(objectstore.NewStoreFixture(t)),
|
||||
}
|
||||
// then
|
||||
status.objectsState.SetSyncStatusAndErr(domain.Synced, domain.Null, "spaceId")
|
||||
status.filesState.SetSyncStatusAndErr(domain.Synced, domain.Null, "spaceId")
|
||||
|
||||
// then
|
||||
syncStatus := domain.MakeSyncStatus("spaceId", domain.Synced, domain.Null, domain.Objects)
|
||||
status.updateSpaceSyncStatus(syncStatus)
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ func (sbt SmartBlockType) IsOneOf(sbts ...SmartBlockType) bool {
|
|||
// Indexable determines if the object of specific type need to be proceeded by the indexer in order to appear in sets
|
||||
func (sbt SmartBlockType) Indexable() (details, outgoingLinks bool) {
|
||||
switch sbt {
|
||||
case SmartBlockTypeDate, SmartBlockTypeAccountOld, SmartBlockTypeArchive, SmartBlockTypeHome:
|
||||
case SmartBlockTypeDate, SmartBlockTypeAccountOld, SmartBlockTypeArchive, SmartBlockTypeHome, SmartBlockTypeNotificationObject:
|
||||
return false, false
|
||||
case SmartBlockTypeWidget:
|
||||
return true, false
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue