Documentation
¶
Overview ¶
Package peersync pulls journal state from peer nodes over the node transport and applies it locally (data sync reconciler).
This is distinct from the workload reconciler (src/reconciler/), which reads local journal events and drives container lifecycle. peersync feeds the journal; the workload reconciler consumes it.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ApplyEvents ¶
func ApplyEvents( ctx context.Context, j journal.Journal, views []journalview.View, byID EventByID, events []journal.Event, ) (applied int, err error)
ApplyEvents appends peer events into the local journal and views, skipping any event whose id is already present (idempotent under pull replay). Returns how many events were newly applied.
func RunPullLoop ¶
func RunPullLoop( ctx context.Context, logger *zap.Logger, selfID uuid.UUID, members MemberSource, syncer PeerSync, j journal.Journal, views []journalview.View, byID EventByID, cursorStore CursorStore, )
RunPullLoop is the peer journal reconciliation loop.
It does not push our events. Each tick it discovers who is alive via memberlist and pulls their journals over the Noise transport, up to maxPagesPerTick pages per peer while each page comes back full:
- On meet: peer is newly seen or has become alive again → Sync once now.
- Periodic: every defaultPullInterval, Sync all still-alive peers (skipped if already synced this tick for a meet).
After each successful Sync, events are applied idempotently (skip known ids) into the local journal and views. The cursor advances only if apply succeeds, in memory and in the store together.
Cursors persist in bbolt through the store, so a restart resumes mid-history instead of re-pulling from event zero. A store load failure starts from empty cursors instead; idempotent apply discards the overlap. A nil store keeps RAM-only behavior and exists for unit tests.
Individual Sync/apply failures are soft-fail (log and continue). The loop blocks until ctx is cancelled.
Types ¶
type CursorStore ¶
type CursorStore interface {
// contains filtered or unexported methods
}
CursorStore persists per-peer sync cursors so a restart resumes mid-history instead of re-pulling from event zero. The bbolt implementation below is the production one; tests and future segment-scoped stores supply their own. A nil store (not an implementation) keeps RAM-only behavior.
func NewCursorStore ¶
func NewCursorStore(kv *kvstore.KVStore) CursorStore
NewCursorStore creates a cursor store backed by the given KVStore.
type EventByID ¶
EventByID can check whether this node already stored an event id. That is all apply needs for dedup. *journalview.EventsByID implements it (Get returns nil, nil when the id is unknown).
type MemberSource ¶
type MemberSource interface {
Members() ([]peerdiscovery.Node, error)
}
MemberSource lists current membership (memberlist). *peerdiscovery.MemberService implements it.
type PeerSync ¶
type PeerSync interface {
Sync(ctx context.Context, peer netip.AddrPort, expect transport.Peer, req transport.SyncRequest) (transport.SyncResponse, error)
}
PeerSync pulls journal state from a peer over the node transport. The concrete client lives in transport.Client (Noise IK unary).