spacesync

package
v0.4.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 23, 2026 License: MIT Imports: 10 Imported by: 0

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL