Documentation
¶
Overview ¶
Package spacesync runs the SDK's space-level catch-up against any-sync's head store at startup.
The per-object Controller.maxAddSeq watermark only advances when an object is loaded (ColdRestore reads from it). Trees that a peer updated while the SDK was offline — or trees the SDK has never opened — stay invisible to derived/queryable surfaces until the user happens to call Get(treeId). This package closes that gap.
Mechanism: persist a single per-space "highest LastAddSeq we have seen" in the SDK DB; on startup, query any-sync's head store for trees whose LastAddSeq exceeds it and force-load each (the existing per-object ColdRestore path then catches them up). Persist the snapshot at the end so the fast path no-ops on the next boot.
The watermark is also snapshotted WITHOUT a replay on clean SDK Close (SnapshotWatermark): everything the head store accepted during a session was applied live as it arrived, so at close time the projection is current and only the persisted number lags. Without that snapshot every tree touched during a session sits above the boot-persisted watermark and the NEXT boot force-loads all of them for nothing.
Run covers only CREATES/UPDATES (force-load trees whose head advanced). The deletion-reconcile backstop for the SDK-DB rebuild case lives in ReconcileDeletions (reconcile.go): a settings-head-gated pass that purges any local row for a tree any-sync has flipped to Deleted.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ReconcileDeletions ¶
func ReconcileDeletions(ctx context.Context, app *anysyncx.App, db anystore.DB, store *spaceobjects.Store, spaceId string) error
ReconcileDeletions purges local projections for objects any-sync has flipped to DeletedStatusDeleted but whose SDK row survived — the sdk.db REBUILD case: any-sync only re-fires the delete callback for Queued ids, and forward catch-up (Run) excludes deleted trees, so a previously-deleted object could otherwise re-surface as a live row (the SDK keeps no `objects` tombstone). Purging also stamps the consumer deletion feed for any surviving row (see spaceobjects.Store.PurgeObjects).
Gated on the any-sync settings-tree head: the settings tree records only deletions, so its head advances iff a deletion happened. On boot we read it and compare against the value persisted on the space's `_meta` row; an unchanged head (and no reconcileVersion bump) means no new deletions since the last sweep — two point reads and return. A wiped sdk.db drops the persisted gate, forcing exactly one sweep.
Sibling of Run (not nested): Run fast-returns on snapshot<=sdkSeq before any deletion logic, and the two gates ("q" watermark vs "dh"/"dv") fire independently. Best-effort, same contract as Run — a returned error means the gate stays stale and the next boot retries.
func Run ¶
func Run(ctx context.Context, app *anysyncx.App, db anystore.DB, store *spaceobjects.Store, spaceId string) error
Run executes one catch-up pass for spaceId. Best-effort by design: per-tree load failures are tolerated (caller logs), and the space watermark is advanced as long as the head-store snapshot read and iteration succeed. Returning an error means the snapshot itself could not be established; the watermark stays at the prior value so the next boot retries.
Cost: one any-store read for the SDK watermark, one any-sync MaxLastAddSeq read, and a filtered IterateEntries that only yields trees with LastAddSeq > sdkSeq (any-sync v0.12.4+ pushes the filter down via IterOpts.MinLastAddSeq). For a steady-state restart with no missed changes, this is two cheap reads and the function returns.
func SnapshotWatermark ¶
func SnapshotWatermark(ctx context.Context, db anystore.DB, handle anysyncx.SpaceHandle, spaceId string) error
SnapshotWatermark persists spaceId's current head-store MaxLastAddSeq as its catch-up watermark without force-loading anything. Called on clean SDK Close for allowlisted spaces only (SDK.caughtUp — caught up by a boot Run or created/derived this session): everything the head store accepted DURING the session was applied to the projection live as it arrived (or parked durably in _detached, which the drainer resumes — the same tolerance Run itself has), so the snapshot is valid and the next boot's Run fast-path no-ops instead of force-loading every tree the session touched. A crash skips this persist and the boot replay remains the fallback. Same snapshot-before-teardown property as Run: anything landing after the read stays above the persisted watermark and replays next boot. The caller must additionally skip spaces with a non-empty treesyncer parked set (App.ParkedTreeCount) — parked trees are storage-committed but never materialized, and the boot replay is their only cross-restart recovery.
Types ¶
This section is empty.