Skip to content

Store: v2 local store, feed and upload effects, change-log reader (DEV-1150 part C) - #50

Merged
adamski merged 14 commits into
mainfrom
adam/dev-1150-store
Sep 29, 2026
Merged

adamski merged 14 commits into
mainfrom
adam/dev-1150-store

Conversation

@adamski

@adamski adamski commented Sep 28, 2026

Copy link
Copy Markdown
Collaborator

DEV-1150 part C: the v2 local store that the driver loop (part D) will run the core against. Stacked on #49 (transport), which is stacked on #48 (engine core). Merge in order: #48, #49, then this.

What's in it

  • Core follow-ups: page upserts keep the envelope seq, and a forbidden scope leaves the core. The connect backoff never drops below 1 s: it uses equal jitter max(1 s, c/2·(1+r)), capped at 60 s. This is a requirement from the 2026-09-28 reconnect-storm incident.
  • Migration 013 (additive). Store::open uses WAL, and every read-then-write runs in one BEGIN IMMEDIATE transaction. Identity is adopted once; after that a mismatch is identity_drift.
  • Snapshots and apply_ops: each rule call's ops go in one transaction. Recover writes the full local content to recovered before the content is replaced.
  • Local write API: create, update and delete. Outbox marker ids per document keep increasing across processes, so an app and a DAW can share one data directory.
  • Feed effects: change pages, snapshot pages, the resync sweep and subscription drops.
  • Upload effects: build, settle, server copy and server-deleted. Settle deletes only the covered rows.
  • Change-log reader: read is the single per-tick entry point. It is woken by data_version, heartbeats when due, and reports DatabaseChanged when trimmed past.
  • Never rebase onto an untrusted base:
    • After a snapshot, pending edits made on v2 go through the conflict path (the local copy is kept in recovered).
    • A doc with no shadow and pending edits takes the conflict path on every path.
    • A migrated shadow at seq 0 still rebases.
    • A randomised property test checks that no edit is lost or applied twice, and that another device's edit is never reverted. The tests were checked by deliberately reintroducing the bugs.

Testing

  • cargo test -p replicant-client --lib: 362 passed. --test wire_contract_tests: 14 passed.
  • No v1 files are changed.

…the core, fuzz checks connect-time sends, reconnect delay never below 1 s
…ency and shadow coverage tests

change_log.rs: a failed heartbeat save inside ChangeLogReader::read no
longer discards the Docs/DatabaseChanged result it already computed; the
error is logged and the heartbeat is retried on the next tick.

uploads.rs: add a test that settling the same Ok(reply) twice for one
upload is a no-op the second time, and assert the new shadow's hash in
the migrated-document conflict-path test.
@adamski
adamski changed the base branch from adam/dev-1150-transport to main September 29, 2026 21:25
@adamski adamski closed this Sep 29, 2026
@adamski adamski reopened this Sep 29, 2026
@adamski
adamski merged commit d0c0262 into main Sep 29, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant