1
0
Fork 0
mirror of https://github.com/anyproto/any-sync.git synced 2025-06-11 10:18:08 +09:00
any-sync/commonspace/sync/sync.go
2024-05-24 11:40:36 +02:00

82 lines
2.4 KiB
Go

package sync
import (
"context"
"github.com/cheggaaa/mb/v3"
"go.uber.org/zap"
"storj.io/drpc"
"github.com/anyproto/any-sync/app/logger"
"github.com/anyproto/any-sync/util/multiqueue"
)
const CName = "common.commonspace.sync"
var log = logger.NewNamed("sync")
type SyncService interface {
GetQueueProvider() multiqueue.QueueProvider[drpc.Message]
}
type MergeFilterFunc func(ctx context.Context, msg drpc.Message, q *mb.MB[drpc.Message]) error
type syncService struct {
// sendQueue is a multiqueue: peerId -> queue
// this queue exists for sending head updates
sendQueueProvider multiqueue.QueueProvider[drpc.Message]
// receiveQueue is a multiqueue: objectId -> queue
// this queue exists for receiving head updates
receiveQueue multiqueue.MultiQueue[drpc.Message]
// manager is a Request manager which works with both incoming and outgoing requests
manager RequestManager
// handler checks if head update is relevant and then queues Request intent if necessary
handler HeadUpdateHandler
// sender sends head updates to peers
sender HeadUpdateSender
mergeFilter MergeFilterFunc
ctx context.Context
cancel context.CancelFunc
}
func NewSyncService() SyncService {
s := &syncService{}
s.ctx, s.cancel = context.WithCancel(context.Background())
s.sendQueueProvider = multiqueue.NewQueueProvider[drpc.Message](100, s.handleOutgoingMessage)
s.receiveQueue = multiqueue.New[drpc.Message](s.handleIncomingMessage, 100)
return s
}
func (s *syncService) handleOutgoingMessage(id string, msg drpc.Message, q *mb.MB[drpc.Message]) error {
return s.mergeFilter(s.ctx, msg, q)
}
func (s *syncService) handleIncomingMessage(msg drpc.Message) {
req, err := s.handler.HandleHeadUpdate(s.ctx, msg)
if err != nil {
log.Error("failed to handle head update", zap.Error(err))
}
if req == nil {
return
}
err = s.manager.QueueRequest(req)
if err != nil {
log.Error("failed to queue request", zap.Error(err))
}
}
func (s *syncService) GetQueueProvider() multiqueue.QueueProvider[drpc.Message] {
return s.sendQueueProvider
}
func (s *syncService) HandleMessage(ctx context.Context, peerId string, msg drpc.Message) error {
return s.receiveQueue.Add(ctx, peerId, msg)
}
func (s *syncService) HandleStreamRequest(ctx context.Context, req Request, stream drpc.Stream) error {
return s.manager.HandleStreamRequest(req, stream)
}
func (s *syncService) NewReadMessage() drpc.Message {
return &HeadUpdate{}
}