1
0
Fork 0
mirror of https://github.com/anyproto/any-sync.git synced 2025-06-08 05:57:03 +09:00

Add space and tree close logic and fix some related tests

This commit is contained in:
mcrakhman 2022-10-19 12:20:24 +02:00 committed by Mikhail Iudin
parent a3f2fb5eae
commit 9692ebe887
No known key found for this signature in database
GPG key ID: FAAAA8BAABDFF1C0
37 changed files with 540 additions and 414 deletions

View file

@ -18,3 +18,61 @@ type Controller interface {
GenerateInvite(spaceId string) (invite string, err error)
JoinSpace(invite string) (err error)
}
type controller struct {
}
func (c *controller) DeriveSpace() (id string, err error) {
//TODO implement me
panic("implement me")
}
func (c *controller) CreateSpace() (id string, err error) {
//TODO implement me
panic("implement me")
}
func (c *controller) GetAllSpacesIds() (ids []string, err error) {
//TODO implement me
panic("implement me")
}
func (c *controller) LoadSpace(id string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *controller) CreateDocument(spaceId string) (id string, err error) {
//TODO implement me
panic("implement me")
}
func (c *controller) GetAllDocumentIds(spaceId string) (ids []string, err error) {
//TODO implement me
panic("implement me")
}
func (c *controller) AddText(documentId, text string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *controller) DumpDocumentTree(documentId string) (err error) {
//TODO implement me
panic("implement me")
}
func (c *controller) GetValidInvites(spaceId string) (invites []string, err error) {
//TODO implement me
panic("implement me")
}
func (c *controller) GenerateInvite(spaceId string) (invite string, err error) {
//TODO implement me
panic("implement me")
}
func (c *controller) JoinSpace(invite string) (err error) {
//TODO implement me
panic("implement me")
}

View file

@ -7,7 +7,8 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/document"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache"
"time"
)
@ -26,7 +27,12 @@ type treeCache struct {
clientService clientspace.Service
}
func New(ttl int) cache.TreeCache {
type TreeCache interface {
treegetter.TreeGetter
GetDocument(ctx context.Context, spaceId, id string) (doc document.TextDocument, err error)
}
func New(ttl int) TreeCache {
return &treeCache{
gcttl: ttl,
}
@ -46,44 +52,38 @@ func (c *treeCache) Init(a *app.App) (err error) {
c.cache = ocache.New(
func(ctx context.Context, id string) (value ocache.Object, err error) {
spaceId := ctx.Value(spaceKey).(string)
container, err := c.clientService.GetSpace(ctx, spaceId)
space, err := c.clientService.GetSpace(ctx, spaceId)
if err != nil {
return
}
defer container.Release()
return document.NewTextDocument(context.Background(), container.Object, id, c.docService)
return document.NewTextDocument(context.Background(), space, id, c.docService)
},
ocache.WithLogger(log.Sugar()),
ocache.WithGCPeriod(time.Minute),
ocache.WithTTL(time.Duration(c.gcttl)*time.Second),
ocache.WithRefCounter(false),
)
return nil
}
func (c *treeCache) Name() (name string) {
return cache.CName
return treegetter.CName
}
func (c *treeCache) GetTree(ctx context.Context, spaceId, id string) (res cache.TreeResult, err error) {
var cacheRes ocache.Object
func (c *treeCache) GetDocument(ctx context.Context, spaceId, id string) (doc document.TextDocument, err error) {
ctx = context.WithValue(ctx, spaceKey, spaceId)
cacheRes, err = c.cache.Get(ctx, id)
v, err := c.cache.Get(ctx, id)
if err != nil {
return cache.TreeResult{}, err
}
treeContainer, ok := cacheRes.(cache.TreeContainer)
if !ok {
err = ErrCacheObjectWithoutTree
return
}
res = cache.TreeResult{
Release: func() {
c.cache.Release(id)
},
TreeContainer: treeContainer,
}
doc = v.(document.TextDocument)
return
}
func (c *treeCache) GetTree(ctx context.Context, spaceId, id string) (tr tree.ObjectTree, err error) {
doc, err := c.GetDocument(ctx, spaceId, id)
if err != nil {
return
}
tr = doc.Tree()
return
}

View file

@ -2,9 +2,9 @@ package clientspace
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
)
type rpcHandler struct {
@ -17,7 +17,7 @@ func (r *rpcHandler) PushSpace(ctx context.Context, req *spacesyncproto.PushSpac
err = spacesyncproto.ErrSpaceExists
return
}
if err != cache.ErrSpaceNotFound {
if err != treegetter.ErrSpaceNotFound {
err = spacesyncproto.ErrUnexpected
return
}

View file

@ -2,7 +2,6 @@ package clientspace
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/util"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace"
@ -23,9 +22,9 @@ func New() Service {
}
type Service interface {
GetSpace(ctx context.Context, id string) (util.ReleaseContainer[commonspace.Space], error)
CreateSpace(ctx context.Context, payload commonspace.SpaceCreatePayload) (util.ReleaseContainer[commonspace.Space], error)
DeriveSpace(ctx context.Context, payload commonspace.SpaceDerivePayload) (util.ReleaseContainer[commonspace.Space], error)
GetSpace(ctx context.Context, id string) (commonspace.Space, error)
CreateSpace(ctx context.Context, payload commonspace.SpaceCreatePayload) (commonspace.Space, error)
DeriveSpace(ctx context.Context, payload commonspace.SpaceDerivePayload) (commonspace.Space, error)
app.ComponentRunnable
}
@ -47,7 +46,6 @@ func (s *service) Init(a *app.App) (err error) {
ocache.WithLogger(log.Sugar()),
ocache.WithGCPeriod(time.Minute),
ocache.WithTTL(time.Duration(s.conf.GCTTL)*time.Second),
ocache.WithRefCounter(false),
)
return spacesyncproto.DRPCRegisterSpace(a.MustComponent(server.CName).(server.DRPCServer), &rpcHandler{s})
}
@ -64,7 +62,7 @@ func (s *service) Run(ctx context.Context) (err error) {
return
}
func (s *service) CreateSpace(ctx context.Context, payload commonspace.SpaceCreatePayload) (container util.ReleaseContainer[commonspace.Space], err error) {
func (s *service) CreateSpace(ctx context.Context, payload commonspace.SpaceCreatePayload) (container commonspace.Space, err error) {
id, err := s.commonSpace.CreateSpace(ctx, payload)
if err != nil {
return
@ -74,15 +72,10 @@ func (s *service) CreateSpace(ctx context.Context, payload commonspace.SpaceCrea
if err != nil {
return
}
return util.ReleaseContainer[commonspace.Space]{
Object: obj.(commonspace.Space),
Release: func() {
s.spaceCache.Release(id)
},
}, nil
return obj.(commonspace.Space), nil
}
func (s *service) DeriveSpace(ctx context.Context, payload commonspace.SpaceDerivePayload) (container util.ReleaseContainer[commonspace.Space], err error) {
func (s *service) DeriveSpace(ctx context.Context, payload commonspace.SpaceDerivePayload) (container commonspace.Space, err error) {
id, err := s.commonSpace.DeriveSpace(ctx, payload)
if err != nil {
return
@ -92,25 +85,15 @@ func (s *service) DeriveSpace(ctx context.Context, payload commonspace.SpaceDeri
if err != nil {
return
}
return util.ReleaseContainer[commonspace.Space]{
Object: obj.(commonspace.Space),
Release: func() {
s.spaceCache.Release(id)
},
}, nil
return obj.(commonspace.Space), nil
}
func (s *service) GetSpace(ctx context.Context, id string) (container util.ReleaseContainer[commonspace.Space], err error) {
func (s *service) GetSpace(ctx context.Context, id string) (container commonspace.Space, err error) {
v, err := s.spaceCache.Get(ctx, id)
if err != nil {
return
}
return util.ReleaseContainer[commonspace.Space]{
Object: v.(commonspace.Space),
Release: func() {
s.spaceCache.Release(id)
},
}, nil
return v.(commonspace.Space), nil
}
func (s *service) Close(ctx context.Context) (err error) {

View file

@ -3,12 +3,14 @@ package document
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/clientspace"
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/clientspace/clientcache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
"go.uber.org/zap"
)
type Service interface {
@ -27,7 +29,7 @@ var log = logger.NewNamed(CName)
type service struct {
account account.Service
spaceService clientspace.Service
cache cache.TreeCache
cache clientcache.TreeCache
}
func New() Service {
@ -37,7 +39,7 @@ func New() Service {
func (s *service) Init(a *app.App) (err error) {
s.account = a.MustComponent(account.CName).(account.Service)
s.spaceService = a.MustComponent(clientspace.CName).(clientspace.Service)
s.cache = a.MustComponent(cache.CName).(cache.TreeCache)
s.cache = a.MustComponent(treegetter.CName).(clientcache.TreeCache)
return
}
@ -46,12 +48,11 @@ func (s *service) Name() (name string) {
}
func (s *service) CreateDocument(spaceId string) (id string, err error) {
spaceRef, err := s.spaceService.GetSpace(context.Background(), spaceId)
space, err := s.spaceService.GetSpace(context.Background(), spaceId)
if err != nil {
return
}
defer spaceRef.Release()
doc, err := createTextDocument(context.Background(), spaceRef.Object, s.account, s)
doc, err := createTextDocument(context.Background(), space, s.account, s)
if err != nil {
return
}
@ -60,38 +61,40 @@ func (s *service) CreateDocument(spaceId string) (id string, err error) {
}
func (s *service) GetAllDocumentIds(spaceId string) (ids []string, err error) {
spaceRef, err := s.spaceService.GetSpace(context.Background(), spaceId)
space, err := s.spaceService.GetSpace(context.Background(), spaceId)
if err != nil {
return
}
defer spaceRef.Release()
ids = spaceRef.Object.StoredIds()
ids = space.StoredIds()
return
}
func (s *service) AddText(spaceId, documentId, text string) (err error) {
doc, err := s.cache.GetTree(context.Background(), spaceId, documentId)
doc, err := s.cache.GetDocument(context.Background(), spaceId, documentId)
if err != nil {
return
}
defer doc.Release()
return doc.TreeContainer.(TextDocument).AddText(text)
return doc.AddText(text)
}
func (s *service) DumpDocumentTree(spaceId, documentId string) (dump string, err error) {
doc, err := s.cache.GetTree(context.Background(), spaceId, documentId)
doc, err := s.cache.GetDocument(context.Background(), spaceId, documentId)
if err != nil {
return
}
defer doc.Release()
return doc.TreeContainer.Tree().DebugDump()
return doc.Tree().DebugDump()
}
func (s *service) Update(tree tree.ObjectTree) {
log.With(
zap.Strings("heads", tree.Heads()),
zap.String("tree id", tree.ID())).
Debug("updating tree")
}
func (s *service) Rebuild(tree tree.ObjectTree) {
//TODO implement me
panic("implement me")
log.With(
zap.Strings("heads", tree.Heads()),
zap.String("tree id", tree.ID())).
Debug("rebuilding tree")
}

View file

@ -4,7 +4,6 @@ import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener"
testchanges "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/testutils/testchanges/proto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
@ -12,7 +11,7 @@ import (
)
type TextDocument interface {
cache.TreeContainer
Tree() tree.ObjectTree
AddText(text string) error
Text() (string, error)
TreeDump() string

View file

@ -1,6 +0,0 @@
package util
type ReleaseContainer[T any] struct {
Object T
Release func()
}

View file

@ -1,30 +0,0 @@
//go:generate mockgen -destination mock_cache/mock_cache.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache TreeCache
package cache
import (
"context"
"errors"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
)
const CName = "commonspace.cache"
var ErrSpaceNotFound = errors.New("space not found")
type TreeContainer interface {
Tree() tree.ObjectTree
}
type TreeResult struct {
Release func()
TreeContainer TreeContainer
}
type BuildFunc = func(ctx context.Context, id string, listener updatelistener.UpdateListener) (tree.ObjectTree, error)
type TreeCache interface {
app.ComponentRunnable
GetTree(ctx context.Context, spaceId, treeId string) (TreeResult, error)
}

View file

@ -3,10 +3,10 @@ package diffservice
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/remotediff"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff"
"go.uber.org/zap"
@ -38,7 +38,7 @@ func NewDiffService(
syncPeriod int,
storage storage.SpaceStorage,
confConnector nodeconf.ConfConnector,
cache cache.TreeCache,
cache treegetter.TreeGetter,
log *zap.Logger) DiffService {
diff := ldiff.New(16, 16)

View file

@ -2,10 +2,10 @@ package diffservice
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/remotediff"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/rpcerr"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf"
@ -22,7 +22,7 @@ func newDiffSyncer(
spaceId string,
diff ldiff.Diff,
confConnector nodeconf.ConfConnector,
cache cache.TreeCache,
cache treegetter.TreeGetter,
storage storage.SpaceStorage,
clientFactory spacesyncproto.ClientFactory,
log *zap.Logger) DiffSyncer {
@ -41,7 +41,7 @@ type diffSyncer struct {
spaceId string
diff ldiff.Diff
confConnector nodeconf.ConfConnector
cache cache.TreeCache
cache treegetter.TreeGetter
storage storage.SpaceStorage
clientFactory spacesyncproto.ClientFactory
log *zap.Logger

View file

@ -4,12 +4,11 @@ import (
"context"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache/mock_cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/remotediff"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto/mock_spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage/mock_storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter/mock_treegetter"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/peer"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf/mock_nodeconf"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
@ -89,7 +88,7 @@ func TestDiffSyncer_Sync(t *testing.T) {
diffMock := mock_ldiff.NewMockDiff(ctrl)
connectorMock := mock_nodeconf.NewMockConfConnector(ctrl)
cacheMock := mock_cache.NewMockTreeCache(ctrl)
cacheMock := mock_treegetter.NewMockTreeGetter(ctrl)
stMock := mock_storage.NewMockSpaceStorage(ctrl)
clientMock := mock_spacesyncproto.NewMockDRPCSpaceClient(ctrl)
factory := spacesyncproto.ClientFactoryFunc(func(cc drpc.Conn) spacesyncproto.DRPCSpaceClient {
@ -109,7 +108,7 @@ func TestDiffSyncer_Sync(t *testing.T) {
for _, arg := range []string{"new", "changed"} {
cacheMock.EXPECT().
GetTree(gomock.Any(), spaceId, arg).
Return(cache.TreeResult{}, nil)
Return(nil, nil)
}
require.NoError(t, diffSyncer.Sync(ctx))
})

View file

@ -4,10 +4,10 @@ import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
config2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/config"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/pool"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf"
@ -32,7 +32,7 @@ type service struct {
config config2.Space
configurationService nodeconf.Service
storageProvider storage.SpaceStorageProvider
cache cache.TreeCache
cache treegetter.TreeGetter
pool pool.Pool
}
@ -40,7 +40,7 @@ func (s *service) Init(a *app.App) (err error) {
s.config = a.MustComponent(config2.CName).(*config2.Config).Space
s.storageProvider = a.MustComponent(storage.CName).(storage.SpaceStorageProvider)
s.configurationService = a.MustComponent(nodeconf.CName).(nodeconf.Service)
s.cache = a.MustComponent(cache.CName).(cache.TreeCache)
s.cache = a.MustComponent(treegetter.CName).(treegetter.TreeGetter)
s.pool = a.MustComponent(pool.CName).(pool.Pool)
return nil
}

View file

@ -2,22 +2,27 @@ package commonspace
import (
"context"
"errors"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list"
storage2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
tree2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/encryptionkey"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/asymmetric/signingkey"
"sync"
"sync/atomic"
"time"
)
var ErrSpaceClosed = errors.New("space is closed")
type SpaceCreatePayload struct {
// SigningKey is the signing key of the owner
SigningKey signingkey.PrivKey
@ -64,8 +69,14 @@ type space struct {
syncService syncservice.SyncService
diffService diffservice.DiffService
storage storage.SpaceStorage
cache cache.TreeCache
cache treegetter.TreeGetter
aclList list.ACLList
isClosed atomic.Bool
}
func (s *space) LastUsage() time.Time {
return s.syncService.LastUsage()
}
func (s *space) Id() string {
@ -99,15 +110,27 @@ func (s *space) StoredIds() []string {
return s.diffService.AllIds()
}
func (s *space) DeriveTree(ctx context.Context, payload tree2.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tree2.ObjectTree, error) {
func (s *space) DeriveTree(ctx context.Context, payload tree2.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tr tree2.ObjectTree, err error) {
if s.isClosed.Load() {
err = ErrSpaceClosed
return
}
return synctree.DeriveSyncTree(ctx, payload, s.syncService.SyncClient(), listener, s.aclList, s.storage.CreateTreeStorage)
}
func (s *space) CreateTree(ctx context.Context, payload tree2.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tree2.ObjectTree, error) {
func (s *space) CreateTree(ctx context.Context, payload tree2.ObjectTreeCreatePayload, listener updatelistener.UpdateListener) (tr tree2.ObjectTree, err error) {
if s.isClosed.Load() {
err = ErrSpaceClosed
return
}
return synctree.CreateSyncTree(ctx, payload, s.syncService.SyncClient(), listener, s.aclList, s.storage.CreateTreeStorage)
}
func (s *space) BuildTree(ctx context.Context, id string, listener updatelistener.UpdateListener) (t tree2.ObjectTree, err error) {
if s.isClosed.Load() {
err = ErrSpaceClosed
return
}
getTreeRemote := func() (*spacesyncproto.ObjectSyncMessage, error) {
// TODO: add empty context handling (when this is not happening due to head update)
peerId, err := syncservice.GetPeerIdFromStreamContext(ctx)
@ -155,6 +178,9 @@ func (s *space) BuildTree(ctx context.Context, id string, listener updatelistene
}
func (s *space) Close() error {
defer func() {
s.isClosed.Store(true)
}()
s.diffService.Close()
s.syncService.Close()
return s.storage.Close()

View file

@ -408,11 +408,11 @@ func (m *ObjectSyncMessage) GetTrackingId() string {
// ObjectSyncContentValue provides different types for object sync
type ObjectSyncContentValue struct {
// Types that are valid to be assigned to Value:
// *ObjectSyncContentValueValueOfHeadUpdate
// *ObjectSyncContentValueValueOfFullSyncRequest
// *ObjectSyncContentValueValueOfFullSyncResponse
// *ObjectSyncContentValueValueOfErrorResponse
Value IsObjectSyncContentValueValue `protobuf_oneof:"value"`
// *ObjectSyncContentValue_HeadUpdate
// *ObjectSyncContentValue_FullSyncRequest
// *ObjectSyncContentValue_FullSyncResponse
// *ObjectSyncContentValue_ErrorResponse
Value isObjectSyncContentValue_Value `protobuf_oneof:"value"`
}
func (m *ObjectSyncContentValue) Reset() { *m = ObjectSyncContentValue{} }
@ -448,31 +448,31 @@ func (m *ObjectSyncContentValue) XXX_DiscardUnknown() {
var xxx_messageInfo_ObjectSyncContentValue proto.InternalMessageInfo
type IsObjectSyncContentValueValue interface {
IsObjectSyncContentValueValue()
type isObjectSyncContentValue_Value interface {
isObjectSyncContentValue_Value()
MarshalTo([]byte) (int, error)
Size() int
}
type ObjectSyncContentValueValueOfHeadUpdate struct {
type ObjectSyncContentValue_HeadUpdate struct {
HeadUpdate *ObjectHeadUpdate `protobuf:"bytes,1,opt,name=headUpdate,proto3,oneof" json:"headUpdate,omitempty"`
}
type ObjectSyncContentValueValueOfFullSyncRequest struct {
type ObjectSyncContentValue_FullSyncRequest struct {
FullSyncRequest *ObjectFullSyncRequest `protobuf:"bytes,2,opt,name=fullSyncRequest,proto3,oneof" json:"fullSyncRequest,omitempty"`
}
type ObjectSyncContentValueValueOfFullSyncResponse struct {
type ObjectSyncContentValue_FullSyncResponse struct {
FullSyncResponse *ObjectFullSyncResponse `protobuf:"bytes,3,opt,name=fullSyncResponse,proto3,oneof" json:"fullSyncResponse,omitempty"`
}
type ObjectSyncContentValueValueOfErrorResponse struct {
type ObjectSyncContentValue_ErrorResponse struct {
ErrorResponse *ObjectErrorResponse `protobuf:"bytes,4,opt,name=errorResponse,proto3,oneof" json:"errorResponse,omitempty"`
}
func (*ObjectSyncContentValueValueOfHeadUpdate) IsObjectSyncContentValueValue() {}
func (*ObjectSyncContentValueValueOfFullSyncRequest) IsObjectSyncContentValueValue() {}
func (*ObjectSyncContentValueValueOfFullSyncResponse) IsObjectSyncContentValueValue() {}
func (*ObjectSyncContentValueValueOfErrorResponse) IsObjectSyncContentValueValue() {}
func (*ObjectSyncContentValue_HeadUpdate) isObjectSyncContentValue_Value() {}
func (*ObjectSyncContentValue_FullSyncRequest) isObjectSyncContentValue_Value() {}
func (*ObjectSyncContentValue_FullSyncResponse) isObjectSyncContentValue_Value() {}
func (*ObjectSyncContentValue_ErrorResponse) isObjectSyncContentValue_Value() {}
func (m *ObjectSyncContentValue) GetValue() IsObjectSyncContentValueValue {
func (m *ObjectSyncContentValue) GetValue() isObjectSyncContentValue_Value {
if m != nil {
return m.Value
}
@ -480,28 +480,28 @@ func (m *ObjectSyncContentValue) GetValue() IsObjectSyncContentValueValue {
}
func (m *ObjectSyncContentValue) GetHeadUpdate() *ObjectHeadUpdate {
if x, ok := m.GetValue().(*ObjectSyncContentValueValueOfHeadUpdate); ok {
if x, ok := m.GetValue().(*ObjectSyncContentValue_HeadUpdate); ok {
return x.HeadUpdate
}
return nil
}
func (m *ObjectSyncContentValue) GetFullSyncRequest() *ObjectFullSyncRequest {
if x, ok := m.GetValue().(*ObjectSyncContentValueValueOfFullSyncRequest); ok {
if x, ok := m.GetValue().(*ObjectSyncContentValue_FullSyncRequest); ok {
return x.FullSyncRequest
}
return nil
}
func (m *ObjectSyncContentValue) GetFullSyncResponse() *ObjectFullSyncResponse {
if x, ok := m.GetValue().(*ObjectSyncContentValueValueOfFullSyncResponse); ok {
if x, ok := m.GetValue().(*ObjectSyncContentValue_FullSyncResponse); ok {
return x.FullSyncResponse
}
return nil
}
func (m *ObjectSyncContentValue) GetErrorResponse() *ObjectErrorResponse {
if x, ok := m.GetValue().(*ObjectSyncContentValueValueOfErrorResponse); ok {
if x, ok := m.GetValue().(*ObjectSyncContentValue_ErrorResponse); ok {
return x.ErrorResponse
}
return nil
@ -510,10 +510,10 @@ func (m *ObjectSyncContentValue) GetErrorResponse() *ObjectErrorResponse {
// XXX_OneofWrappers is for the internal use of the proto package.
func (*ObjectSyncContentValue) XXX_OneofWrappers() []interface{} {
return []interface{}{
(*ObjectSyncContentValueValueOfHeadUpdate)(nil),
(*ObjectSyncContentValueValueOfFullSyncRequest)(nil),
(*ObjectSyncContentValueValueOfFullSyncResponse)(nil),
(*ObjectSyncContentValueValueOfErrorResponse)(nil),
(*ObjectSyncContentValue_HeadUpdate)(nil),
(*ObjectSyncContentValue_FullSyncRequest)(nil),
(*ObjectSyncContentValue_FullSyncResponse)(nil),
(*ObjectSyncContentValue_ErrorResponse)(nil),
}
}
@ -1410,12 +1410,12 @@ func (m *ObjectSyncContentValue) MarshalToSizedBuffer(dAtA []byte) (int, error)
return len(dAtA) - i, nil
}
func (m *ObjectSyncContentValueValueOfHeadUpdate) MarshalTo(dAtA []byte) (int, error) {
func (m *ObjectSyncContentValue_HeadUpdate) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ObjectSyncContentValueValueOfHeadUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *ObjectSyncContentValue_HeadUpdate) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
if m.HeadUpdate != nil {
{
@ -1431,12 +1431,12 @@ func (m *ObjectSyncContentValueValueOfHeadUpdate) MarshalToSizedBuffer(dAtA []by
}
return len(dAtA) - i, nil
}
func (m *ObjectSyncContentValueValueOfFullSyncRequest) MarshalTo(dAtA []byte) (int, error) {
func (m *ObjectSyncContentValue_FullSyncRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ObjectSyncContentValueValueOfFullSyncRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *ObjectSyncContentValue_FullSyncRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
if m.FullSyncRequest != nil {
{
@ -1452,12 +1452,12 @@ func (m *ObjectSyncContentValueValueOfFullSyncRequest) MarshalToSizedBuffer(dAtA
}
return len(dAtA) - i, nil
}
func (m *ObjectSyncContentValueValueOfFullSyncResponse) MarshalTo(dAtA []byte) (int, error) {
func (m *ObjectSyncContentValue_FullSyncResponse) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ObjectSyncContentValueValueOfFullSyncResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *ObjectSyncContentValue_FullSyncResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
if m.FullSyncResponse != nil {
{
@ -1473,12 +1473,12 @@ func (m *ObjectSyncContentValueValueOfFullSyncResponse) MarshalToSizedBuffer(dAt
}
return len(dAtA) - i, nil
}
func (m *ObjectSyncContentValueValueOfErrorResponse) MarshalTo(dAtA []byte) (int, error) {
func (m *ObjectSyncContentValue_ErrorResponse) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ObjectSyncContentValueValueOfErrorResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *ObjectSyncContentValue_ErrorResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
if m.ErrorResponse != nil {
{
@ -2030,7 +2030,7 @@ func (m *ObjectSyncContentValue) Size() (n int) {
return n
}
func (m *ObjectSyncContentValueValueOfHeadUpdate) Size() (n int) {
func (m *ObjectSyncContentValue_HeadUpdate) Size() (n int) {
if m == nil {
return 0
}
@ -2042,7 +2042,7 @@ func (m *ObjectSyncContentValueValueOfHeadUpdate) Size() (n int) {
}
return n
}
func (m *ObjectSyncContentValueValueOfFullSyncRequest) Size() (n int) {
func (m *ObjectSyncContentValue_FullSyncRequest) Size() (n int) {
if m == nil {
return 0
}
@ -2054,7 +2054,7 @@ func (m *ObjectSyncContentValueValueOfFullSyncRequest) Size() (n int) {
}
return n
}
func (m *ObjectSyncContentValueValueOfFullSyncResponse) Size() (n int) {
func (m *ObjectSyncContentValue_FullSyncResponse) Size() (n int) {
if m == nil {
return 0
}
@ -2066,7 +2066,7 @@ func (m *ObjectSyncContentValueValueOfFullSyncResponse) Size() (n int) {
}
return n
}
func (m *ObjectSyncContentValueValueOfErrorResponse) Size() (n int) {
func (m *ObjectSyncContentValue_ErrorResponse) Size() (n int) {
if m == nil {
return 0
}
@ -3103,7 +3103,7 @@ func (m *ObjectSyncContentValue) Unmarshal(dAtA []byte) error {
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Value = &ObjectSyncContentValueValueOfHeadUpdate{v}
m.Value = &ObjectSyncContentValue_HeadUpdate{v}
iNdEx = postIndex
case 2:
if wireType != 2 {
@ -3138,7 +3138,7 @@ func (m *ObjectSyncContentValue) Unmarshal(dAtA []byte) error {
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Value = &ObjectSyncContentValueValueOfFullSyncRequest{v}
m.Value = &ObjectSyncContentValue_FullSyncRequest{v}
iNdEx = postIndex
case 3:
if wireType != 2 {
@ -3173,7 +3173,7 @@ func (m *ObjectSyncContentValue) Unmarshal(dAtA []byte) error {
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Value = &ObjectSyncContentValueValueOfFullSyncResponse{v}
m.Value = &ObjectSyncContentValue_FullSyncResponse{v}
iNdEx = postIndex
case 4:
if wireType != 2 {
@ -3208,7 +3208,7 @@ func (m *ObjectSyncContentValue) Unmarshal(dAtA []byte) error {
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Value = &ObjectSyncContentValueValueOfErrorResponse{v}
m.Value = &ObjectSyncContentValue_ErrorResponse{v}
iNdEx = postIndex
default:
iNdEx = preIndex

View file

@ -5,12 +5,12 @@
package mock_storage
import (
storage2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
reflect "reflect"
app "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
spacesyncproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
storage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
storage0 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
gomock "github.com/golang/mock/gomock"
)
@ -119,10 +119,10 @@ func (m *MockSpaceStorage) EXPECT() *MockSpaceStorageMockRecorder {
}
// ACLStorage mocks base method.
func (m *MockSpaceStorage) ACLStorage() (storage2.ListStorage, error) {
func (m *MockSpaceStorage) ACLStorage() (storage0.ListStorage, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ACLStorage")
ret0, _ := ret[0].(storage2.ListStorage)
ret0, _ := ret[0].(storage0.ListStorage)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@ -148,10 +148,10 @@ func (mr *MockSpaceStorageMockRecorder) Close() *gomock.Call {
}
// CreateTreeStorage mocks base method.
func (m *MockSpaceStorage) CreateTreeStorage(arg0 storage2.TreeStorageCreatePayload) (storage2.TreeStorage, error) {
func (m *MockSpaceStorage) CreateTreeStorage(arg0 storage0.TreeStorageCreatePayload) (storage0.TreeStorage, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateTreeStorage", arg0)
ret0, _ := ret[0].(storage2.TreeStorage)
ret0, _ := ret[0].(storage0.TreeStorage)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@ -208,10 +208,10 @@ func (mr *MockSpaceStorageMockRecorder) StoredIds() *gomock.Call {
}
// TreeStorage mocks base method.
func (m *MockSpaceStorage) TreeStorage(arg0 string) (storage2.TreeStorage, error) {
func (m *MockSpaceStorage) TreeStorage(arg0 string) (storage0.TreeStorage, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "TreeStorage", arg0)
ret0, _ := ret[0].(storage2.TreeStorage)
ret0, _ := ret[0].(storage0.TreeStorage)
ret1, _ := ret[1].(error)
return ret0, ret1
}

View file

@ -5,11 +5,12 @@
package mock_syncservice
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
reflect "reflect"
time "time"
spacesyncproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
tree "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
treechangeproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
gomock "github.com/golang/mock/gomock"
)
@ -176,6 +177,20 @@ func (mr *MockSyncClientMockRecorder) HasActiveStream(arg0 interface{}) *gomock.
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasActiveStream", reflect.TypeOf((*MockSyncClient)(nil).HasActiveStream), arg0)
}
// LastUsage mocks base method.
func (m *MockSyncClient) LastUsage() time.Time {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "LastUsage")
ret0, _ := ret[0].(time.Time)
return ret0
}
// LastUsage indicates an expected call of LastUsage.
func (mr *MockSyncClientMockRecorder) LastUsage() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastUsage", reflect.TypeOf((*MockSyncClient)(nil).LastUsage))
}
// SendAsync mocks base method.
func (m *MockSyncClient) SendAsync(arg0 []string, arg1 *spacesyncproto.ObjectSyncMessage) error {
m.ctrl.T.Helper()

View file

@ -5,10 +5,12 @@ import (
"errors"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache"
"github.com/libp2p/go-libp2p-core/sec"
"storj.io/drpc/drpcctx"
"sync"
"sync/atomic"
"time"
)
var ErrEmptyPeer = errors.New("don't have such a peer")
@ -19,6 +21,7 @@ const maxSimultaneousOperationsPerStream = 10
// StreamPool can be made generic to work with different streams
type StreamPool interface {
Sender
ocache.ObjectLastUsage
AddAndReadStreamSync(stream spacesyncproto.SpaceStream) (err error)
AddAndReadStreamAsync(stream spacesyncproto.SpaceStream)
HasActiveStream(peerId string) bool
@ -44,7 +47,8 @@ type streamPool struct {
wg *sync.WaitGroup
waiters map[string]responseWaiter
waitersMx sync.Mutex
counter uint64
counter atomic.Uint64
lastUsage atomic.Int64
}
func newStreamPool(messageHandler MessageHandler) StreamPool {
@ -55,6 +59,10 @@ func newStreamPool(messageHandler MessageHandler) StreamPool {
}
}
func (s *streamPool) LastUsage() time.Time {
return time.Unix(s.lastUsage.Load(), 0)
}
func (s *streamPool) HasActiveStream(peerId string) (res bool) {
s.Lock()
defer s.Unlock()
@ -65,7 +73,7 @@ func (s *streamPool) HasActiveStream(peerId string) (res bool) {
func (s *streamPool) SendSync(
peerId string,
msg *spacesyncproto.ObjectSyncMessage) (reply *spacesyncproto.ObjectSyncMessage, err error) {
newCounter := atomic.AddUint64(&s.counter, 1)
newCounter := s.counter.Add(1)
msg.TrackingId = genStreamPoolKey(peerId, msg.TreeId, newCounter)
s.waitersMx.Lock()
@ -85,6 +93,7 @@ func (s *streamPool) SendSync(
}
func (s *streamPool) SendAsync(peers []string, message *spacesyncproto.ObjectSyncMessage) (err error) {
s.lastUsage.Store(time.Now().Unix())
getStreams := func() (streams []spacesyncproto.SpaceStream) {
for _, pId := range peers {
stream, err := s.getOrDeleteStream(pId)
@ -101,9 +110,10 @@ func (s *streamPool) SendAsync(peers []string, message *spacesyncproto.ObjectSyn
s.Unlock()
for _, s := range streams {
if len(peers) == 1 {
err = s.Send(message)
}
err = s.Send(message)
}
if len(peers) != 1 {
err = nil
}
return err
}
@ -191,6 +201,7 @@ func (s *streamPool) readPeerLoop(peerId string, stream spacesyncproto.SpaceStre
}
process := func(msg *spacesyncproto.ObjectSyncMessage) {
s.lastUsage.Store(time.Now().Unix())
if msg.TrackingId == "" {
s.messageHandler(stream.Context(), peerId, msg)
return
@ -213,6 +224,7 @@ func (s *streamPool) readPeerLoop(peerId string, stream spacesyncproto.SpaceStre
Loop:
for {
msg, err := stream.Recv()
s.lastUsage.Store(time.Now().Unix())
if err != nil {
break
}

View file

@ -3,11 +3,14 @@ package syncservice
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache"
"time"
)
type SyncClient interface {
StreamPool
RequestFactory
ocache.ObjectLastUsage
BroadcastAsyncOrSendResponsible(message *spacesyncproto.ObjectSyncMessage) (err error)
}
@ -29,6 +32,10 @@ func newSyncClient(spaceId string, pool StreamPool, notifiable HeadNotifiable, f
}
}
func (s *syncClient) LastUsage() time.Time {
return s.StreamPool.LastUsage()
}
func (s *syncClient) BroadcastAsync(message *spacesyncproto.ObjectSyncMessage) (err error) {
s.notifyIfNeeded(message)
return s.BroadcastAsync(message)

View file

@ -2,15 +2,15 @@ package syncservice
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/slice"
)
type syncHandler struct {
spaceId string
treeCache cache.TreeCache
treeCache treegetter.TreeGetter
syncClient SyncClient
}
@ -18,7 +18,7 @@ type SyncHandler interface {
HandleMessage(ctx context.Context, senderId string, request *spacesyncproto.ObjectSyncMessage) (err error)
}
func newSyncHandler(spaceId string, treeCache cache.TreeCache, syncClient SyncClient) *syncHandler {
func newSyncHandler(spaceId string, treeCache treegetter.TreeGetter, syncClient SyncClient) *syncHandler {
return &syncHandler{
spaceId: spaceId,
treeCache: treeCache,
@ -49,15 +49,13 @@ func (s *syncHandler) handleHeadUpdate(
fullRequest *spacesyncproto.ObjectSyncMessage
isEmptyUpdate = len(update.Changes) == 0
)
res, err := s.treeCache.GetTree(ctx, s.spaceId, msg.TreeId)
objTree, err := s.treeCache.GetTree(ctx, s.spaceId, msg.TreeId)
if err != nil {
return
}
err = func() error {
objTree := res.TreeContainer.Tree()
objTree.Lock()
defer res.Release()
defer objTree.Unlock()
// isEmptyUpdate is sent when the tree is brought up from cache
@ -108,15 +106,13 @@ func (s *syncHandler) handleFullSyncRequest(
}
}()
res, err := s.treeCache.GetTree(ctx, s.spaceId, msg.TreeId)
objTree, err := s.treeCache.GetTree(ctx, s.spaceId, msg.TreeId)
if err != nil {
return
}
err = func() error {
objTree := res.TreeContainer.Tree()
objTree.Lock()
defer res.Release()
defer objTree.Unlock()
if header == nil {
@ -145,15 +141,13 @@ func (s *syncHandler) handleFullSyncResponse(
senderId string,
response *spacesyncproto.ObjectFullSyncResponse,
msg *spacesyncproto.ObjectSyncMessage) (err error) {
res, err := s.treeCache.GetTree(ctx, s.spaceId, msg.TreeId)
objTree, err := s.treeCache.GetTree(ctx, s.spaceId, msg.TreeId)
if err != nil {
return
}
err = func() error {
objTree := res.TreeContainer.Tree()
objTree.Lock()
defer res.Release()
defer objTree.Unlock()
if s.alreadyHasHeads(objTree, response.Heads) {

View file

@ -3,10 +3,9 @@ package syncservice
import (
"context"
"fmt"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache/mock_cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice/mock_syncservice"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter/mock_treegetter"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree/mock_objecttree"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
@ -49,7 +48,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) {
ctx := context.Background()
spaceId := "spaceId"
cacheMock := mock_cache.NewMockTreeCache(ctrl)
cacheMock := mock_treegetter.NewMockTreeGetter(ctrl)
syncClientMock := mock_syncservice.NewMockSyncClient(ctrl)
objectTreeMock := newTestObjMock(mock_tree.NewMockObjectTree(ctrl))
@ -66,10 +65,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) {
msg := spacesyncproto.WrapHeadUpdate(headUpdate, chWithId, treeId, "")
cacheMock.EXPECT().
GetTree(gomock.Any(), spaceId, treeId).
Return(cache.TreeResult{
Release: func() {},
TreeContainer: treeContainer{objectTreeMock},
}, nil)
Return(objectTreeMock, nil)
objectTreeMock.EXPECT().
Heads().
Return([]string{"h2"})
@ -103,10 +99,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) {
msg := spacesyncproto.WrapHeadUpdate(headUpdate, chWithId, treeId, "")
cacheMock.EXPECT().
GetTree(gomock.Any(), spaceId, treeId).
Return(cache.TreeResult{
Release: func() {},
TreeContainer: treeContainer{objectTreeMock},
}, nil)
Return(objectTreeMock, nil)
objectTreeMock.EXPECT().
Heads().
Return([]string{"h2"})
@ -143,10 +136,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) {
msg := spacesyncproto.WrapHeadUpdate(headUpdate, chWithId, treeId, "")
cacheMock.EXPECT().
GetTree(gomock.Any(), spaceId, treeId).
Return(cache.TreeResult{
Release: func() {},
TreeContainer: treeContainer{objectTreeMock},
}, nil)
Return(objectTreeMock, nil)
objectTreeMock.EXPECT().
Heads().
Return([]string{"h1"})
@ -168,10 +158,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) {
msg := spacesyncproto.WrapHeadUpdate(headUpdate, chWithId, treeId, "")
cacheMock.EXPECT().
GetTree(gomock.Any(), spaceId, treeId).
Return(cache.TreeResult{
Release: func() {},
TreeContainer: treeContainer{objectTreeMock},
}, nil)
Return(objectTreeMock, nil)
objectTreeMock.EXPECT().
Heads().
Return([]string{"h2"})
@ -196,10 +183,7 @@ func TestSyncHandler_HandleHeadUpdate(t *testing.T) {
msg := spacesyncproto.WrapHeadUpdate(headUpdate, chWithId, treeId, "")
cacheMock.EXPECT().
GetTree(gomock.Any(), spaceId, treeId).
Return(cache.TreeResult{
Release: func() {},
TreeContainer: treeContainer{objectTreeMock},
}, nil)
Return(objectTreeMock, nil)
objectTreeMock.EXPECT().
Heads().
@ -216,7 +200,7 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) {
ctx := context.Background()
spaceId := "spaceId"
cacheMock := mock_cache.NewMockTreeCache(ctrl)
cacheMock := mock_treegetter.NewMockTreeGetter(ctrl)
syncClientMock := mock_syncservice.NewMockSyncClient(ctrl)
objectTreeMock := newTestObjMock(mock_tree.NewMockObjectTree(ctrl))
@ -234,10 +218,7 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) {
cacheMock.EXPECT().
GetTree(gomock.Any(), spaceId, treeId).
Return(cache.TreeResult{
Release: func() {},
TreeContainer: treeContainer{objectTreeMock},
}, nil)
Return(objectTreeMock, nil)
objectTreeMock.EXPECT().
Heads().
Return([]string{"h2"})
@ -269,10 +250,7 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) {
cacheMock.EXPECT().
GetTree(gomock.Any(), spaceId, treeId).
Return(cache.TreeResult{
Release: func() {},
TreeContainer: treeContainer{objectTreeMock},
}, nil)
Return(objectTreeMock, nil)
objectTreeMock.EXPECT().
Heads().
Return([]string{"h2"})
@ -297,10 +275,7 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) {
cacheMock.EXPECT().
GetTree(gomock.Any(), spaceId, treeId).
Return(cache.TreeResult{
Release: func() {},
TreeContainer: treeContainer{objectTreeMock},
}, nil)
Return(objectTreeMock, nil)
syncClientMock.EXPECT().
CreateFullSyncResponse(gomock.Eq(objectTreeMock), gomock.Eq([]string{"h1"}), gomock.Eq([]string{"h1"}), gomock.Eq("")).
Return(fullRequest, nil)
@ -321,7 +296,7 @@ func TestSyncHandler_HandleFullSyncRequest(t *testing.T) {
cacheMock.EXPECT().
GetTree(gomock.Any(), spaceId, treeId).
Return(cache.TreeResult{}, fmt.Errorf("some"))
Return(nil, fmt.Errorf("some"))
syncClientMock.EXPECT().
SendAsync(gomock.Eq([]string{senderId}), gomock.Any())
@ -336,7 +311,7 @@ func TestSyncHandler_HandleFullSyncResponse(t *testing.T) {
ctx := context.Background()
spaceId := "spaceId"
cacheMock := mock_cache.NewMockTreeCache(ctrl)
cacheMock := mock_treegetter.NewMockTreeGetter(ctrl)
syncClientMock := mock_syncservice.NewMockSyncClient(ctrl)
objectTreeMock := newTestObjMock(mock_tree.NewMockObjectTree(ctrl))
@ -353,10 +328,7 @@ func TestSyncHandler_HandleFullSyncResponse(t *testing.T) {
cacheMock.EXPECT().
GetTree(gomock.Any(), spaceId, treeId).
Return(cache.TreeResult{
Release: func() {},
TreeContainer: treeContainer{objectTreeMock},
}, nil)
Return(objectTreeMock, nil)
objectTreeMock.EXPECT().
Heads().
Return([]string{"h2"})
@ -383,10 +355,7 @@ func TestSyncHandler_HandleFullSyncResponse(t *testing.T) {
cacheMock.EXPECT().
GetTree(gomock.Any(), spaceId, treeId).
Return(cache.TreeResult{
Release: func() {},
TreeContainer: treeContainer{objectTreeMock},
}, nil)
Return(objectTreeMock, nil)
objectTreeMock.EXPECT().
Heads().
Return([]string{"h1"})

View file

@ -4,16 +4,18 @@ package syncservice
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/rpcerr"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/nodeconf"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache"
"time"
)
var log = logger.NewNamed("syncservice").Sugar()
type SyncService interface {
ocache.ObjectLastUsage
SyncClient() SyncClient
Init()
@ -41,7 +43,7 @@ type syncService struct {
func NewSyncService(
spaceId string,
headNotifiable HeadNotifiable,
cache cache.TreeCache,
cache treegetter.TreeGetter,
configuration nodeconf.Configuration,
confConnector nodeconf.ConfConnector) SyncService {
var syncHandler SyncHandler
@ -58,6 +60,10 @@ func NewSyncService(
confConnector)
}
func (s *syncService) LastUsage() time.Time {
return s.syncClient.LastUsage()
}
func newSyncService(
spaceId string,
syncClient SyncClient,

View file

@ -2,6 +2,7 @@ package synctree
import (
"context"
"errors"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/synctree/updatelistener"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list"
@ -10,11 +11,14 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
)
var ErrSyncTreeClosed = errors.New("sync tree is closed")
// SyncTree sends head updates to sync service and also sends new changes to update listener
type SyncTree struct {
tree2.ObjectTree
syncClient syncservice.SyncClient
listener updatelistener.UpdateListener
isClosed bool
}
var createDerivedObjectTree = tree2.CreateDerivedObjectTree
@ -97,6 +101,10 @@ func buildSyncTree(
}
func (s *SyncTree) AddContent(ctx context.Context, content tree2.SignableChangeContent) (res tree2.AddResult, err error) {
if s.isClosed {
err = ErrSyncTreeClosed
return
}
res, err = s.ObjectTree.AddContent(ctx, content)
if err != nil {
return
@ -107,6 +115,10 @@ func (s *SyncTree) AddContent(ctx context.Context, content tree2.SignableChangeC
}
func (s *SyncTree) AddRawChanges(ctx context.Context, changes ...*treechangeproto.RawTreeChangeWithId) (res tree2.AddResult, err error) {
if s.isClosed {
err = ErrSyncTreeClosed
return
}
res, err = s.ObjectTree.AddRawChanges(ctx, changes...)
if err != nil {
return
@ -125,6 +137,17 @@ func (s *SyncTree) AddRawChanges(ctx context.Context, changes ...*treechangeprot
return
}
func (s *SyncTree) Close() (err error) {
s.Lock()
defer s.Unlock()
if s.isClosed {
err = ErrSyncTreeClosed
return
}
s.isClosed = true
return
}
func (s *SyncTree) Tree() tree2.ObjectTree {
return s
}

View file

@ -5,9 +5,9 @@
package mock_updatelistener
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
reflect "reflect"
tree "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
gomock "github.com/golang/mock/gomock"
)

View file

@ -1,43 +1,43 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache (interfaces: TreeCache)
// Source: github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter (interfaces: TreeGetter)
// Package mock_cache is a generated GoMock package.
package mock_cache
// Package mock_treegetter is a generated GoMock package.
package mock_treegetter
import (
context "context"
reflect "reflect"
app "github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
cache "github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
tree "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
gomock "github.com/golang/mock/gomock"
)
// MockTreeCache is a mock of TreeCache interface.
type MockTreeCache struct {
// MockTreeGetter is a mock of TreeGetter interface.
type MockTreeGetter struct {
ctrl *gomock.Controller
recorder *MockTreeCacheMockRecorder
recorder *MockTreeGetterMockRecorder
}
// MockTreeCacheMockRecorder is the mock recorder for MockTreeCache.
type MockTreeCacheMockRecorder struct {
mock *MockTreeCache
// MockTreeGetterMockRecorder is the mock recorder for MockTreeGetter.
type MockTreeGetterMockRecorder struct {
mock *MockTreeGetter
}
// NewMockTreeCache creates a new mock instance.
func NewMockTreeCache(ctrl *gomock.Controller) *MockTreeCache {
mock := &MockTreeCache{ctrl: ctrl}
mock.recorder = &MockTreeCacheMockRecorder{mock}
// NewMockTreeGetter creates a new mock instance.
func NewMockTreeGetter(ctrl *gomock.Controller) *MockTreeGetter {
mock := &MockTreeGetter{ctrl: ctrl}
mock.recorder = &MockTreeGetterMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockTreeCache) EXPECT() *MockTreeCacheMockRecorder {
func (m *MockTreeGetter) EXPECT() *MockTreeGetterMockRecorder {
return m.recorder
}
// Close mocks base method.
func (m *MockTreeCache) Close(arg0 context.Context) error {
func (m *MockTreeGetter) Close(arg0 context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Close", arg0)
ret0, _ := ret[0].(error)
@ -45,28 +45,28 @@ func (m *MockTreeCache) Close(arg0 context.Context) error {
}
// Close indicates an expected call of Close.
func (mr *MockTreeCacheMockRecorder) Close(arg0 interface{}) *gomock.Call {
func (mr *MockTreeGetterMockRecorder) Close(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockTreeCache)(nil).Close), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockTreeGetter)(nil).Close), arg0)
}
// GetTree mocks base method.
func (m *MockTreeCache) GetTree(arg0 context.Context, arg1, arg2 string) (cache.TreeResult, error) {
func (m *MockTreeGetter) GetTree(arg0 context.Context, arg1, arg2 string) (tree.ObjectTree, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetTree", arg0, arg1, arg2)
ret0, _ := ret[0].(cache.TreeResult)
ret0, _ := ret[0].(tree.ObjectTree)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetTree indicates an expected call of GetTree.
func (mr *MockTreeCacheMockRecorder) GetTree(arg0, arg1, arg2 interface{}) *gomock.Call {
func (mr *MockTreeGetterMockRecorder) GetTree(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTree", reflect.TypeOf((*MockTreeCache)(nil).GetTree), arg0, arg1, arg2)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTree", reflect.TypeOf((*MockTreeGetter)(nil).GetTree), arg0, arg1, arg2)
}
// Init mocks base method.
func (m *MockTreeCache) Init(arg0 *app.App) error {
func (m *MockTreeGetter) Init(arg0 *app.App) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Init", arg0)
ret0, _ := ret[0].(error)
@ -74,13 +74,13 @@ func (m *MockTreeCache) Init(arg0 *app.App) error {
}
// Init indicates an expected call of Init.
func (mr *MockTreeCacheMockRecorder) Init(arg0 interface{}) *gomock.Call {
func (mr *MockTreeGetterMockRecorder) Init(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockTreeCache)(nil).Init), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockTreeGetter)(nil).Init), arg0)
}
// Name mocks base method.
func (m *MockTreeCache) Name() string {
func (m *MockTreeGetter) Name() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Name")
ret0, _ := ret[0].(string)
@ -88,13 +88,13 @@ func (m *MockTreeCache) Name() string {
}
// Name indicates an expected call of Name.
func (mr *MockTreeCacheMockRecorder) Name() *gomock.Call {
func (mr *MockTreeGetterMockRecorder) Name() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockTreeCache)(nil).Name))
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockTreeGetter)(nil).Name))
}
// Run mocks base method.
func (m *MockTreeCache) Run(arg0 context.Context) error {
func (m *MockTreeGetter) Run(arg0 context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Run", arg0)
ret0, _ := ret[0].(error)
@ -102,7 +102,7 @@ func (m *MockTreeCache) Run(arg0 context.Context) error {
}
// Run indicates an expected call of Run.
func (mr *MockTreeCacheMockRecorder) Run(arg0 interface{}) *gomock.Call {
func (mr *MockTreeGetterMockRecorder) Run(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockTreeCache)(nil).Run), arg0)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Run", reflect.TypeOf((*MockTreeGetter)(nil).Run), arg0)
}

View file

@ -0,0 +1,18 @@
//go:generate mockgen -destination mock_treegetter/mock_treegetter.go github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter TreeGetter
package treegetter
import (
"context"
"errors"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
)
const CName = "commonspace.treeGetter"
var ErrSpaceNotFound = errors.New("space not found")
type TreeGetter interface {
app.ComponentRunnable
GetTree(ctx context.Context, spaceId, treeId string) (tree.ObjectTree, error)
}

View file

@ -54,7 +54,6 @@ func (p *pool) Init(a *app.App) (err error) {
ocache.WithLogger(log.Sugar()),
ocache.WithGCPeriod(time.Minute),
ocache.WithTTL(time.Minute*5),
ocache.WithRefCounter(false),
)
return nil
}

View file

@ -324,12 +324,13 @@ func (m *ACLRoot) GetTimestamp() int64 {
type ACLContentValue struct {
// Types that are valid to be assigned to Value:
// *ACLContentValueValueOfUserAdd
// *ACLContentValueValueOfUserRemove
// *ACLContentValueValueOfUserPermissionChange
// *ACLContentValueValueOfUserInvite
// *ACLContentValueValueOfUserJoin
Value IsACLContentValueValue `protobuf_oneof:"value"`
//
// *ACLContentValue_UserAdd
// *ACLContentValue_UserRemove
// *ACLContentValue_UserPermissionChange
// *ACLContentValue_UserInvite
// *ACLContentValue_UserJoin
Value isACLContentValue_Value `protobuf_oneof:"value"`
}
func (m *ACLContentValue) Reset() { *m = ACLContentValue{} }
@ -365,35 +366,35 @@ func (m *ACLContentValue) XXX_DiscardUnknown() {
var xxx_messageInfo_ACLContentValue proto.InternalMessageInfo
type IsACLContentValueValue interface {
IsACLContentValueValue()
type isACLContentValue_Value interface {
isACLContentValue_Value()
MarshalTo([]byte) (int, error)
Size() int
}
type ACLContentValueValueOfUserAdd struct {
type ACLContentValue_UserAdd struct {
UserAdd *ACLUserAdd `protobuf:"bytes,1,opt,name=userAdd,proto3,oneof" json:"userAdd,omitempty"`
}
type ACLContentValueValueOfUserRemove struct {
type ACLContentValue_UserRemove struct {
UserRemove *ACLUserRemove `protobuf:"bytes,2,opt,name=userRemove,proto3,oneof" json:"userRemove,omitempty"`
}
type ACLContentValueValueOfUserPermissionChange struct {
type ACLContentValue_UserPermissionChange struct {
UserPermissionChange *ACLUserPermissionChange `protobuf:"bytes,3,opt,name=userPermissionChange,proto3,oneof" json:"userPermissionChange,omitempty"`
}
type ACLContentValueValueOfUserInvite struct {
type ACLContentValue_UserInvite struct {
UserInvite *ACLUserInvite `protobuf:"bytes,4,opt,name=userInvite,proto3,oneof" json:"userInvite,omitempty"`
}
type ACLContentValueValueOfUserJoin struct {
type ACLContentValue_UserJoin struct {
UserJoin *ACLUserJoin `protobuf:"bytes,5,opt,name=userJoin,proto3,oneof" json:"userJoin,omitempty"`
}
func (*ACLContentValueValueOfUserAdd) IsACLContentValueValue() {}
func (*ACLContentValueValueOfUserRemove) IsACLContentValueValue() {}
func (*ACLContentValueValueOfUserPermissionChange) IsACLContentValueValue() {}
func (*ACLContentValueValueOfUserInvite) IsACLContentValueValue() {}
func (*ACLContentValueValueOfUserJoin) IsACLContentValueValue() {}
func (*ACLContentValue_UserAdd) isACLContentValue_Value() {}
func (*ACLContentValue_UserRemove) isACLContentValue_Value() {}
func (*ACLContentValue_UserPermissionChange) isACLContentValue_Value() {}
func (*ACLContentValue_UserInvite) isACLContentValue_Value() {}
func (*ACLContentValue_UserJoin) isACLContentValue_Value() {}
func (m *ACLContentValue) GetValue() IsACLContentValueValue {
func (m *ACLContentValue) GetValue() isACLContentValue_Value {
if m != nil {
return m.Value
}
@ -401,35 +402,35 @@ func (m *ACLContentValue) GetValue() IsACLContentValueValue {
}
func (m *ACLContentValue) GetUserAdd() *ACLUserAdd {
if x, ok := m.GetValue().(*ACLContentValueValueOfUserAdd); ok {
if x, ok := m.GetValue().(*ACLContentValue_UserAdd); ok {
return x.UserAdd
}
return nil
}
func (m *ACLContentValue) GetUserRemove() *ACLUserRemove {
if x, ok := m.GetValue().(*ACLContentValueValueOfUserRemove); ok {
if x, ok := m.GetValue().(*ACLContentValue_UserRemove); ok {
return x.UserRemove
}
return nil
}
func (m *ACLContentValue) GetUserPermissionChange() *ACLUserPermissionChange {
if x, ok := m.GetValue().(*ACLContentValueValueOfUserPermissionChange); ok {
if x, ok := m.GetValue().(*ACLContentValue_UserPermissionChange); ok {
return x.UserPermissionChange
}
return nil
}
func (m *ACLContentValue) GetUserInvite() *ACLUserInvite {
if x, ok := m.GetValue().(*ACLContentValueValueOfUserInvite); ok {
if x, ok := m.GetValue().(*ACLContentValue_UserInvite); ok {
return x.UserInvite
}
return nil
}
func (m *ACLContentValue) GetUserJoin() *ACLUserJoin {
if x, ok := m.GetValue().(*ACLContentValueValueOfUserJoin); ok {
if x, ok := m.GetValue().(*ACLContentValue_UserJoin); ok {
return x.UserJoin
}
return nil
@ -438,11 +439,11 @@ func (m *ACLContentValue) GetUserJoin() *ACLUserJoin {
// XXX_OneofWrappers is for the internal use of the proto package.
func (*ACLContentValue) XXX_OneofWrappers() []interface{} {
return []interface{}{
(*ACLContentValueValueOfUserAdd)(nil),
(*ACLContentValueValueOfUserRemove)(nil),
(*ACLContentValueValueOfUserPermissionChange)(nil),
(*ACLContentValueValueOfUserInvite)(nil),
(*ACLContentValueValueOfUserJoin)(nil),
(*ACLContentValue_UserAdd)(nil),
(*ACLContentValue_UserRemove)(nil),
(*ACLContentValue_UserPermissionChange)(nil),
(*ACLContentValue_UserInvite)(nil),
(*ACLContentValue_UserJoin)(nil),
}
}
@ -1303,12 +1304,12 @@ func (m *ACLContentValue) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *ACLContentValueValueOfUserAdd) MarshalTo(dAtA []byte) (int, error) {
func (m *ACLContentValue_UserAdd) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ACLContentValueValueOfUserAdd) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *ACLContentValue_UserAdd) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
if m.UserAdd != nil {
{
@ -1324,12 +1325,12 @@ func (m *ACLContentValueValueOfUserAdd) MarshalToSizedBuffer(dAtA []byte) (int,
}
return len(dAtA) - i, nil
}
func (m *ACLContentValueValueOfUserRemove) MarshalTo(dAtA []byte) (int, error) {
func (m *ACLContentValue_UserRemove) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ACLContentValueValueOfUserRemove) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *ACLContentValue_UserRemove) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
if m.UserRemove != nil {
{
@ -1345,12 +1346,12 @@ func (m *ACLContentValueValueOfUserRemove) MarshalToSizedBuffer(dAtA []byte) (in
}
return len(dAtA) - i, nil
}
func (m *ACLContentValueValueOfUserPermissionChange) MarshalTo(dAtA []byte) (int, error) {
func (m *ACLContentValue_UserPermissionChange) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ACLContentValueValueOfUserPermissionChange) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *ACLContentValue_UserPermissionChange) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
if m.UserPermissionChange != nil {
{
@ -1366,12 +1367,12 @@ func (m *ACLContentValueValueOfUserPermissionChange) MarshalToSizedBuffer(dAtA [
}
return len(dAtA) - i, nil
}
func (m *ACLContentValueValueOfUserInvite) MarshalTo(dAtA []byte) (int, error) {
func (m *ACLContentValue_UserInvite) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ACLContentValueValueOfUserInvite) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *ACLContentValue_UserInvite) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
if m.UserInvite != nil {
{
@ -1387,12 +1388,12 @@ func (m *ACLContentValueValueOfUserInvite) MarshalToSizedBuffer(dAtA []byte) (in
}
return len(dAtA) - i, nil
}
func (m *ACLContentValueValueOfUserJoin) MarshalTo(dAtA []byte) (int, error) {
func (m *ACLContentValue_UserJoin) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ACLContentValueValueOfUserJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *ACLContentValue_UserJoin) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
if m.UserJoin != nil {
{
@ -1979,7 +1980,7 @@ func (m *ACLContentValue) Size() (n int) {
return n
}
func (m *ACLContentValueValueOfUserAdd) Size() (n int) {
func (m *ACLContentValue_UserAdd) Size() (n int) {
if m == nil {
return 0
}
@ -1991,7 +1992,7 @@ func (m *ACLContentValueValueOfUserAdd) Size() (n int) {
}
return n
}
func (m *ACLContentValueValueOfUserRemove) Size() (n int) {
func (m *ACLContentValue_UserRemove) Size() (n int) {
if m == nil {
return 0
}
@ -2003,7 +2004,7 @@ func (m *ACLContentValueValueOfUserRemove) Size() (n int) {
}
return n
}
func (m *ACLContentValueValueOfUserPermissionChange) Size() (n int) {
func (m *ACLContentValue_UserPermissionChange) Size() (n int) {
if m == nil {
return 0
}
@ -2015,7 +2016,7 @@ func (m *ACLContentValueValueOfUserPermissionChange) Size() (n int) {
}
return n
}
func (m *ACLContentValueValueOfUserInvite) Size() (n int) {
func (m *ACLContentValue_UserInvite) Size() (n int) {
if m == nil {
return 0
}
@ -2027,7 +2028,7 @@ func (m *ACLContentValueValueOfUserInvite) Size() (n int) {
}
return n
}
func (m *ACLContentValueValueOfUserJoin) Size() (n int) {
func (m *ACLContentValue_UserJoin) Size() (n int) {
if m == nil {
return 0
}
@ -2996,7 +2997,7 @@ func (m *ACLContentValue) Unmarshal(dAtA []byte) error {
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Value = &ACLContentValueValueOfUserAdd{v}
m.Value = &ACLContentValue_UserAdd{v}
iNdEx = postIndex
case 2:
if wireType != 2 {
@ -3031,7 +3032,7 @@ func (m *ACLContentValue) Unmarshal(dAtA []byte) error {
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Value = &ACLContentValueValueOfUserRemove{v}
m.Value = &ACLContentValue_UserRemove{v}
iNdEx = postIndex
case 3:
if wireType != 2 {
@ -3066,7 +3067,7 @@ func (m *ACLContentValue) Unmarshal(dAtA []byte) error {
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Value = &ACLContentValueValueOfUserPermissionChange{v}
m.Value = &ACLContentValue_UserPermissionChange{v}
iNdEx = postIndex
case 4:
if wireType != 2 {
@ -3101,7 +3102,7 @@ func (m *ACLContentValue) Unmarshal(dAtA []byte) error {
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Value = &ACLContentValueValueOfUserInvite{v}
m.Value = &ACLContentValue_UserInvite{v}
iNdEx = postIndex
case 5:
if wireType != 2 {
@ -3136,7 +3137,7 @@ func (m *ACLContentValue) Unmarshal(dAtA []byte) error {
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Value = &ACLContentValueValueOfUserJoin{v}
m.Value = &ACLContentValue_UserJoin{v}
iNdEx = postIndex
default:
iNdEx = preIndex

View file

@ -5,10 +5,10 @@
package mock_list
import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
list2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list"
reflect "reflect"
aclrecordproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
list "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/list"
gomock "github.com/golang/mock/gomock"
)
@ -36,10 +36,10 @@ func (m *MockACLList) EXPECT() *MockACLListMockRecorder {
}
// ACLState mocks base method.
func (m *MockACLList) ACLState() *list2.ACLState {
func (m *MockACLList) ACLState() *list.ACLState {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ACLState")
ret0, _ := ret[0].(*list2.ACLState)
ret0, _ := ret[0].(*list.ACLState)
return ret0
}
@ -64,10 +64,10 @@ func (mr *MockACLListMockRecorder) Close() *gomock.Call {
}
// Get mocks base method.
func (m *MockACLList) Get(arg0 string) (*list2.ACLRecord, error) {
func (m *MockACLList) Get(arg0 string) (*list.ACLRecord, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Get", arg0)
ret0, _ := ret[0].(*list2.ACLRecord)
ret0, _ := ret[0].(*list.ACLRecord)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@ -79,10 +79,10 @@ func (mr *MockACLListMockRecorder) Get(arg0 interface{}) *gomock.Call {
}
// Head mocks base method.
func (m *MockACLList) Head() *list2.ACLRecord {
func (m *MockACLList) Head() *list.ACLRecord {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Head")
ret0, _ := ret[0].(*list2.ACLRecord)
ret0, _ := ret[0].(*list.ACLRecord)
return ret0
}
@ -122,7 +122,7 @@ func (mr *MockACLListMockRecorder) IsAfter(arg0, arg1 interface{}) *gomock.Call
}
// Iterate mocks base method.
func (m *MockACLList) Iterate(arg0 func(*list2.ACLRecord) bool) {
func (m *MockACLList) Iterate(arg0 func(*list.ACLRecord) bool) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "Iterate", arg0)
}
@ -134,7 +134,7 @@ func (mr *MockACLListMockRecorder) Iterate(arg0 interface{}) *gomock.Call {
}
// IterateFrom mocks base method.
func (m *MockACLList) IterateFrom(arg0 string, arg1 func(*list2.ACLRecord) bool) {
func (m *MockACLList) IterateFrom(arg0 string, arg1 func(*list.ACLRecord) bool) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "IterateFrom", arg0, arg1)
}
@ -182,10 +182,10 @@ func (mr *MockACLListMockRecorder) RUnlock() *gomock.Call {
}
// Records mocks base method.
func (m *MockACLList) Records() []*list2.ACLRecord {
func (m *MockACLList) Records() []*list.ACLRecord {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Records")
ret0, _ := ret[0].([]*list2.ACLRecord)
ret0, _ := ret[0].([]*list.ACLRecord)
return ret0
}

View file

@ -6,10 +6,10 @@ package mock_storage
import (
context "context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
reflect "reflect"
aclrecordproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
treechangeproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
gomock "github.com/golang/mock/gomock"
)

View file

@ -24,8 +24,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
type TextContent struct {
// Types that are valid to be assigned to Value:
// *TextContentValueOfTextAppend
Value IsTextContentValue `protobuf_oneof:"value"`
//
// *TextContent_TextAppend
Value isTextContent_Value `protobuf_oneof:"value"`
}
func (m *TextContent) Reset() { *m = TextContent{} }
@ -61,19 +62,19 @@ func (m *TextContent) XXX_DiscardUnknown() {
var xxx_messageInfo_TextContent proto.InternalMessageInfo
type IsTextContentValue interface {
IsTextContentValue()
type isTextContent_Value interface {
isTextContent_Value()
MarshalTo([]byte) (int, error)
Size() int
}
type TextContentValueOfTextAppend struct {
type TextContent_TextAppend struct {
TextAppend *TextAppend `protobuf:"bytes,1,opt,name=textAppend,proto3,oneof" json:"textAppend,omitempty"`
}
func (*TextContentValueOfTextAppend) IsTextContentValue() {}
func (*TextContent_TextAppend) isTextContent_Value() {}
func (m *TextContent) GetValue() IsTextContentValue {
func (m *TextContent) GetValue() isTextContent_Value {
if m != nil {
return m.Value
}
@ -81,7 +82,7 @@ func (m *TextContent) GetValue() IsTextContentValue {
}
func (m *TextContent) GetTextAppend() *TextAppend {
if x, ok := m.GetValue().(*TextContentValueOfTextAppend); ok {
if x, ok := m.GetValue().(*TextContent_TextAppend); ok {
return x.TextAppend
}
return nil
@ -90,7 +91,7 @@ func (m *TextContent) GetTextAppend() *TextAppend {
// XXX_OneofWrappers is for the internal use of the proto package.
func (*TextContent) XXX_OneofWrappers() []interface{} {
return []interface{}{
(*TextContentValueOfTextAppend)(nil),
(*TextContent_TextAppend)(nil),
}
}
@ -297,12 +298,12 @@ func (m *TextContent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *TextContentValueOfTextAppend) MarshalTo(dAtA []byte) (int, error) {
func (m *TextContent_TextAppend) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *TextContentValueOfTextAppend) MarshalToSizedBuffer(dAtA []byte) (int, error) {
func (m *TextContent_TextAppend) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
if m.TextAppend != nil {
{
@ -450,7 +451,7 @@ func (m *TextContent) Size() (n int) {
return n
}
func (m *TextContentValueOfTextAppend) Size() (n int) {
func (m *TextContent_TextAppend) Size() (n int) {
if m == nil {
return 0
}
@ -575,7 +576,7 @@ func (m *TextContent) Unmarshal(dAtA []byte) error {
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Value = &TextContentValueOfTextAppend{v}
m.Value = &TextContent_TextAppend{v}
iNdEx = postIndex
default:
iNdEx = preIndex

View file

@ -6,11 +6,11 @@ package mock_tree
import (
context "context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
tree2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
reflect "reflect"
storage "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
tree "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
treechangeproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/treechangeproto"
gomock "github.com/golang/mock/gomock"
)
@ -38,10 +38,10 @@ func (m *MockObjectTree) EXPECT() *MockObjectTreeMockRecorder {
}
// AddContent mocks base method.
func (m *MockObjectTree) AddContent(arg0 context.Context, arg1 tree2.SignableChangeContent) (tree2.AddResult, error) {
func (m *MockObjectTree) AddContent(arg0 context.Context, arg1 tree.SignableChangeContent) (tree.AddResult, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AddContent", arg0, arg1)
ret0, _ := ret[0].(tree2.AddResult)
ret0, _ := ret[0].(tree.AddResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@ -53,14 +53,14 @@ func (mr *MockObjectTreeMockRecorder) AddContent(arg0, arg1 interface{}) *gomock
}
// AddRawChanges mocks base method.
func (m *MockObjectTree) AddRawChanges(arg0 context.Context, arg1 ...*treechangeproto.RawTreeChangeWithId) (tree2.AddResult, error) {
func (m *MockObjectTree) AddRawChanges(arg0 context.Context, arg1 ...*treechangeproto.RawTreeChangeWithId) (tree.AddResult, error) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0}
for _, a := range arg1 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "AddRawChanges", varargs...)
ret0, _ := ret[0].(tree2.AddResult)
ret0, _ := ret[0].(tree.AddResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
@ -177,7 +177,7 @@ func (mr *MockObjectTreeMockRecorder) ID() *gomock.Call {
}
// Iterate mocks base method.
func (m *MockObjectTree) Iterate(arg0 func([]byte) (interface{}, error), arg1 func(*tree2.Change) bool) error {
func (m *MockObjectTree) Iterate(arg0 func([]byte) (interface{}, error), arg1 func(*tree.Change) bool) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Iterate", arg0, arg1)
ret0, _ := ret[0].(error)
@ -191,7 +191,7 @@ func (mr *MockObjectTreeMockRecorder) Iterate(arg0, arg1 interface{}) *gomock.Ca
}
// IterateFrom mocks base method.
func (m *MockObjectTree) IterateFrom(arg0 string, arg1 func([]byte) (interface{}, error), arg2 func(*tree2.Change) bool) error {
func (m *MockObjectTree) IterateFrom(arg0 string, arg1 func([]byte) (interface{}, error), arg2 func(*tree.Change) bool) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "IterateFrom", arg0, arg1, arg2)
ret0, _ := ret[0].(error)
@ -241,10 +241,10 @@ func (mr *MockObjectTreeMockRecorder) RUnlock() *gomock.Call {
}
// Root mocks base method.
func (m *MockObjectTree) Root() *tree2.Change {
func (m *MockObjectTree) Root() *tree.Change {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Root")
ret0, _ := ret[0].(*tree2.Change)
ret0, _ := ret[0].(*tree.Change)
return ret0
}

View file

@ -6,9 +6,9 @@ package mock_ldiff
import (
context "context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff"
reflect "reflect"
ldiff "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ldiff"
gomock "github.com/golang/mock/gomock"
)
@ -52,6 +52,34 @@ func (mr *MockDiffMockRecorder) Diff(arg0, arg1 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Diff", reflect.TypeOf((*MockDiff)(nil).Diff), arg0, arg1)
}
// Elements mocks base method.
func (m *MockDiff) Elements() []ldiff.Element {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Elements")
ret0, _ := ret[0].([]ldiff.Element)
return ret0
}
// Elements indicates an expected call of Elements.
func (mr *MockDiffMockRecorder) Elements() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Elements", reflect.TypeOf((*MockDiff)(nil).Elements))
}
// Ids mocks base method.
func (m *MockDiff) Ids() []string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Ids")
ret0, _ := ret[0].([]string)
return ret0
}
// Ids indicates an expected call of Ids.
func (mr *MockDiffMockRecorder) Ids() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ids", reflect.TypeOf((*MockDiff)(nil).Ids))
}
// Ranges mocks base method.
func (m *MockDiff) Ranges(arg0 context.Context, arg1 []ldiff.Range, arg2 []ldiff.RangeResult) ([]ldiff.RangeResult, error) {
m.ctrl.T.Helper()

View file

@ -46,7 +46,7 @@ var WithGCPeriod = func(gcPeriod time.Duration) Option {
var WithRefCounter = func(enable bool) Option {
return func(cache *oCache) {
cache.noRefCounter = !enable
cache.refCounter = enable
}
}
@ -85,9 +85,11 @@ type entry struct {
id string
lastUsage time.Time
refCount uint32
isClosing bool
load chan struct{}
loadErr error
value Object
close chan struct{}
}
func (e *entry) locked() bool {
@ -129,17 +131,17 @@ type OCache interface {
}
type oCache struct {
mu sync.Mutex
data map[string]*entry
loadFunc LoadFunc
timeNow func() time.Time
ttl time.Duration
gc time.Duration
closed bool
closeCh chan struct{}
log *zap.SugaredLogger
metrics *metrics
noRefCounter bool
mu sync.Mutex
data map[string]*entry
loadFunc LoadFunc
timeNow func() time.Time
ttl time.Duration
gc time.Duration
closed bool
closeCh chan struct{}
log *zap.SugaredLogger
metrics *metrics
refCounter bool
}
func (c *oCache) Get(ctx context.Context, id string) (value Object, err error) {
@ -148,6 +150,7 @@ func (c *oCache) Get(ctx context.Context, id string) (value Object, err error) {
ok bool
load bool
)
Load:
c.mu.Lock()
if c.closed {
c.mu.Unlock()
@ -161,11 +164,18 @@ func (c *oCache) Get(ctx context.Context, id string) (value Object, err error) {
}
c.data[id] = e
}
e.lastUsage = c.timeNow()
if !c.noRefCounter {
e.refCount++
closing := e.isClosing
if !e.isClosing {
e.lastUsage = c.timeNow()
if c.refCounter {
e.refCount++
}
}
c.mu.Unlock()
if closing {
<-e.close
goto Load
}
if load {
go c.load(ctx, id, e)
@ -188,20 +198,22 @@ func (c *oCache) Get(ctx context.Context, id string) (value Object, err error) {
func (c *oCache) Pick(ctx context.Context, id string) (value Object, err error) {
c.mu.Lock()
val, ok := c.data[id]
c.mu.Unlock()
if !ok {
if !ok || val.isClosing {
c.mu.Unlock()
return nil, ErrNotExists
}
c.mu.Unlock()
if c.metrics != nil {
c.metrics.hit.Inc()
}
select {
case <-ctx.Done():
return nil, ctx.Err()
case <-val.load:
return val.value, val.loadErr
}
<-val.load
return val.value, val.loadErr
}
func (c *oCache) load(ctx context.Context, id string, e *entry) {
@ -225,7 +237,7 @@ func (c *oCache) Release(id string) bool {
return false
}
if e, ok := c.data[id]; ok {
if !c.noRefCounter && e.refCount > 0 {
if c.refCounter && e.refCount > 0 {
e.refCount--
return true
}
@ -248,17 +260,30 @@ func (c *oCache) Reset(id string) bool {
func (c *oCache) Remove(id string) (ok bool, err error) {
c.mu.Lock()
e, ok := c.data[id]
if ok {
delete(c.data, id)
if c.closed {
c.mu.Unlock()
err = ErrClosed
return
}
var e *entry
e, ok = c.data[id]
if !ok || e.isClosing {
c.mu.Unlock()
return
}
e.isClosing = true
e.close = make(chan struct{})
c.mu.Unlock()
if ok {
<-e.load
if e.value != nil {
err = e.value.Close()
}
<-e.load
if e.value != nil {
err = e.value.Close()
}
c.mu.Lock()
close(e.close)
delete(c.data, e.id)
c.mu.Unlock()
return
}
@ -298,7 +323,7 @@ func (c *oCache) ForEach(f func(obj Object) (isContinue bool)) {
for _, v := range c.data {
select {
case <-v.load:
if v.value != nil {
if v.value != nil && !v.isClosing {
objects = append(objects, v.value)
}
default:
@ -333,19 +358,23 @@ func (c *oCache) GC() {
}
deadline := c.timeNow().Add(-c.ttl)
var toClose []*entry
for k, e := range c.data {
for _, e := range c.data {
if e.isClosing {
continue
}
lu := e.lastUsage
if lug, ok := e.value.(ObjectLastUsage); ok {
lu = lug.LastUsage()
}
if !e.locked() && e.refCount <= 0 && lu.Before(deadline) {
delete(c.data, k)
e.isClosing = true
e.close = make(chan struct{})
toClose = append(toClose, e)
}
}
size := len(c.data)
c.mu.Unlock()
c.log.Infof("GC: removed %d; cache size: %d", len(toClose), size)
for _, e := range toClose {
<-e.load
if e.value != nil {
@ -354,9 +383,16 @@ func (c *oCache) GC() {
}
}
}
c.log.Infof("GC: removed %d; cache size: %d", len(toClose), size)
if len(toClose) > 0 && c.metrics != nil {
c.metrics.gc.Add(float64(len(toClose)))
}
c.mu.Lock()
for _, e := range toClose {
close(e.close)
delete(c.data, e.id)
}
c.mu.Unlock()
}
func (c *oCache) Len() int {

View file

@ -51,7 +51,6 @@ func (s *service) Init(a *app.App) (err error) {
cacheOpts := []ocache2.Option{
ocache2.WithTTL(cacheTTL),
ocache2.WithRefCounter(false),
ocache2.WithLogger(log.Named("cache").Sugar()),
}
if ms := a.Component(metric.CName); ms != nil {

View file

@ -5,7 +5,8 @@ import (
"errors"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/tree"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/ocache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/node/nodespace"
"time"
@ -24,7 +25,7 @@ type treeCache struct {
nodeService nodespace.Service
}
func New(ttl int) cache.TreeCache {
func New(ttl int) treegetter.TreeGetter {
return &treeCache{
gcttl: ttl,
}
@ -52,34 +53,20 @@ func (c *treeCache) Init(a *app.App) (err error) {
ocache.WithLogger(log.Sugar()),
ocache.WithGCPeriod(time.Minute),
ocache.WithTTL(time.Duration(c.gcttl)*time.Second),
ocache.WithRefCounter(false),
)
return nil
}
func (c *treeCache) Name() (name string) {
return cache.CName
return treegetter.CName
}
func (c *treeCache) GetTree(ctx context.Context, spaceId, id string) (res cache.TreeResult, err error) {
var cacheRes ocache.Object
func (c *treeCache) GetTree(ctx context.Context, spaceId, id string) (tr tree.ObjectTree, err error) {
ctx = context.WithValue(ctx, spaceKey, spaceId)
cacheRes, err = c.cache.Get(ctx, id)
value, err := c.cache.Get(ctx, id)
if err != nil {
return cache.TreeResult{}, err
}
treeContainer, ok := cacheRes.(cache.TreeContainer)
if !ok {
err = ErrCacheObjectWithoutTree
return
}
res = cache.TreeResult{
Release: func() {
c.cache.Release(id)
},
TreeContainer: treeContainer,
}
tr = value.(tree.ObjectTree)
return
}

View file

@ -2,9 +2,9 @@ package nodespace
import (
"context"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/cache"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
)
type rpcHandler struct {
@ -17,7 +17,7 @@ func (r *rpcHandler) PushSpace(ctx context.Context, req *spacesyncproto.PushSpac
err = spacesyncproto.ErrSpaceExists
return
}
if err != cache.ErrSpaceNotFound {
if err != treegetter.ErrSpaceNotFound {
err = spacesyncproto.ErrUnexpected
return
}

View file

@ -44,7 +44,6 @@ func (s *service) Init(a *app.App) (err error) {
ocache.WithLogger(log.Sugar()),
ocache.WithGCPeriod(time.Minute),
ocache.WithTTL(time.Duration(s.conf.GCTTL)*time.Second),
ocache.WithRefCounter(false),
)
return spacesyncproto.DRPCRegisterSpace(a.MustComponent(server.CName).(server.DRPCServer), &rpcHandler{s})
}