Documentation
¶
Overview ¶
Package readsync moves read state between an account's devices: it publishes each object's seen-heads frontier to the TECH space's key-value store and merges other devices' published frontiers into the local per-space readstate engines. The tech space keeps read positions private (owner-only ACL) — nothing here is visible to other members of the target space.
One KV key per tracked object, `read/<spaceId>/<objectId>`; the store keys rows per (key, peerId), so every device owns its row (LWW on the writer timestamp) and the logical frontier is the union of all rows, folded in by the engine's idempotent MergeHeads.
A merge NEVER loads the object: it runs against the readstate rows (plus point lookups into any-sync's change storage for gap traversal), serialized per object by keyed mutexes, in its own write transaction. The live hook (App.OnKeyValues) hands work to a single worker goroutine; durability comes from Reconcile, which replays every published frontier for a space through the same idempotent merge (one state read per already-merged object).
Index ¶
- Variables
- type EngineFor
- type KVStore
- type Service
- func (s *Service) Close()
- func (s *Service) MarkRead(ctx context.Context, spaceId, objectId string, changeIds []string) (readstate.MarkResult, error)
- func (s *Service) MarkReadUpTo(ctx context.Context, spaceId, objectId, upTo string) (readstate.MarkResult, error)
- func (s *Service) OnKeyValues(decryptor keyvaluestorage.Decryptor, kvs []innerstorage.KeyValue)
- func (s *Service) PruneSpace(ctx context.Context, spaceId string) error
- func (s *Service) PublishedFrontiers(ctx context.Context, spaceId, objectId string) ([][]string, error)
- func (s *Service) Reconcile(ctx context.Context, spaceId string) error
- func (s *Service) ReconcileAll(ctx context.Context) error
Constants ¶
This section is empty.
Variables ¶
var ErrUntracked = errors.New("readsync: space read state not tracked")
ErrUntracked is returned by marks when EngineFor yields no engine: the space tracks no datasets, or the liveness gate dropped it (deleted / pending / unknown at mark time). spaceimpl maps it to the public space.ErrSpaceNotTracked.
Functions ¶
This section is empty.
Types ¶
type EngineFor ¶
EngineFor routes a merge to the target space's readstate engine. nil = space unknown here or tracks nothing (the value is dropped; Reconcile picks it up if the space registers tracking later).
type KVStore ¶
type KVStore func(ctx context.Context) (keyvaluestorage.Storage, error)
KVStore returns the tech space's default key-value store.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func (*Service) MarkRead ¶
func (s *Service) MarkRead(ctx context.Context, spaceId, objectId string, changeIds []string) (readstate.MarkResult, error)
MarkRead covers the given changes (and ancestry) locally, then publishes the advanced frontier. The local commit is the durable step; publishing writes the device's KV row, which any-sync persists locally and syncs when connectivity allows.
func (*Service) MarkReadUpTo ¶
func (s *Service) MarkReadUpTo(ctx context.Context, spaceId, objectId, upTo string) (readstate.MarkResult, error)
MarkReadUpTo covers everything at or below upTo in local display order ("" = all) in bounded per-chunk transactions, then publishes the final frontier once.
func (*Service) OnKeyValues ¶
func (s *Service) OnKeyValues(decryptor keyvaluestorage.Decryptor, kvs []innerstorage.KeyValue)
OnKeyValues is the live hook for the tech space's applied KV writes (wire via App.OnKeyValues). Runs on any-sync's apply path — it only decodes and enqueues; merging happens on the service worker.
func (*Service) PruneSpace ¶
PruneSpace publishes a deletion watermark for the space's read/ keys when any visible frontier row remains — the cleanup for removed spaces (SYN-104). Joining re-seeds read state, so removed spaces' frontiers have no restore value; the watermark physically drops them on every replica. Idempotent and self-clearing: once applied the prefix reads empty and further calls are no-ops, and a row published later by a device that had not yet seen the removal makes the next reconcile pass re-issue the watermark.
func (*Service) PublishedFrontiers ¶
func (s *Service) PublishedFrontiers(ctx context.Context, spaceId, objectId string) ([][]string, error)
PublishedFrontiers returns every device's published frontier for the object — own rows included (a rebuilt device's previous publishes are valid coverage). nil when nothing was published. Used by the first-load seed to prefer the account's real read state over first-sight seeding.
func (*Service) Reconcile ¶
Reconcile replays every frontier published for spaceId through the idempotent merge — the durable complement to the best-effort live hook. Call on boot after the space's store is up. Already-merged frontiers cost one state read each (engine fast path).
Own-device rows are merged too: after a local DB rebuild our own published frontier is the record of this device's reads. And when the local frontier has advanced past our published row (a publish that failed after its mark committed, or marks made before a rebuild), Reconcile republishes — so boot is the healing pass for both directions of divergence.
func (*Service) ReconcileAll ¶
ReconcileAll is the boot form: ONE pass over the tech-space store covering every space (keys route by their embedded spaceId; spaces without a tracked engine are skipped), instead of a full store scan per space.