1
0
Fork 0
mirror of https://github.com/anyproto/any-sync.git synced 2025-06-08 05:57:03 +09:00
any-sync/commonspace/object/tree/synctree/treeremotegetter.go
2024-12-09 11:51:06 +01:00

92 lines
2.3 KiB
Go

package synctree
import (
"context"
"errors"
"github.com/anyproto/any-sync/commonspace/object/tree/objecttree"
"github.com/anyproto/any-sync/commonspace/object/tree/treestorage"
"github.com/anyproto/any-sync/net/peer"
)
var (
ErrNoResponsiblePeers = errors.New("no responsible peers")
)
type treeGetter interface {
getTree(ctx context.Context) (treeStorage objecttree.Storage, peerId string, err error)
}
type treeRemoteGetter struct {
deps BuildDeps
treeId string
}
var createCollector = newFullResponseCollector
func (t treeRemoteGetter) getPeers(ctx context.Context) (peerIds []string, err error) {
peerId, err := peer.CtxPeerId(ctx)
if err != nil {
return nil, err
}
if peerId != peer.CtxResponsiblePeers {
peerIds = []string{peerId}
return
}
log.InfoCtx(ctx, "use responsible peers")
respPeers, err := t.deps.PeerGetter.GetResponsiblePeers(ctx)
if err != nil {
return
}
if len(respPeers) == 0 {
err = ErrNoResponsiblePeers
return
}
for _, p := range respPeers {
peerIds = append(peerIds, p.Id())
}
return
}
func (t treeRemoteGetter) treeRequest(ctx context.Context, peerId string) (collector *fullResponseCollector, err error) {
collector = createCollector(t.deps)
req := t.deps.SyncClient.CreateNewTreeRequest(peerId, t.treeId)
err = t.deps.SyncClient.SendTreeRequest(ctx, req, collector)
if err != nil {
return nil, err
}
return collector, nil
}
func (t treeRemoteGetter) treeRequestLoop(ctx context.Context) (collector *fullResponseCollector, peerId string, err error) {
availablePeers, err := t.getPeers(ctx)
if err != nil {
return
}
peerId = availablePeers[0]
// in future we will try to load from different peers
collector, err = t.treeRequest(ctx, peerId)
return collector, peerId, err
}
func (t treeRemoteGetter) getTree(ctx context.Context) (treeStorage objecttree.Storage, peerId string, err error) {
treeStorage, err = t.deps.SpaceStorage.TreeStorage(ctx, t.treeId)
if err == nil || !errors.Is(err, treestorage.ErrUnknownTreeId) {
return
}
err = checkTreeDeleted(ctx, t.treeId, t.deps.SpaceStorage)
if err != nil {
return
}
collector, peerId, err := t.treeRequestLoop(ctx)
if err != nil {
if errors.Is(err, peer.ErrPeerIdNotFoundInContext) {
err = treestorage.ErrUnknownTreeId
}
return
}
return collector.objectTree.Storage(), peerId, nil
}