Repository navigation
Persist bounded realtime invalidation replay across restarts and servers - #461
Conversation
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
Durable cross-server replay remains subject to two moderate review issues and warrants final human review.
Review effort: Lite
Findings: None
What changed in this PR
Adds opt-in durable realtime replay with transactional journaling, authenticated cursors, bounded retention, restart recovery, and PostgreSQL cross-server support.
Changes:
- Adds durable journal capture and replay.
- Integrates mutation capture, startup initialization, configuration, and metadata.
- Adds tests, CI coverage, documentation, and changelog updates.
| File | Summary |
|---|---|
tests/admin/test_durable_realtime.py |
Adds restart, rollback, privacy, expiry, and PostgreSQL coverage. |
src/root.zig |
Registers durable replay tests. |
src/realtime/durable.zig |
Implements journaling, cursors, retention, concurrency logic, and tests. Moderate review issue: assert the specific lock-timeout error instead of swallowing all failures. |
src/framework.zig |
Initializes durable replay at startup. |
src/api/records.zig |
Captures REST mutations transactionally. |
src/api/realtime_backfill.zig |
Serves durable replay pages. Moderate review issue: map ReplayFrameTooLarge to the documented 409 reset response. |
src/api/meta.zig |
Exposes replay capabilities. |
docs/framework.md |
Documents build options. |
docs/api.md |
Documents durable replay behavior. |
changelog.d/durable-realtime.md |
Records the feature. |
build.zig |
Adds replay configuration flags and limits. |
BACKLOG.md |
Updates replay tracking. |
.github/workflows/ci.yml |
Adds durable replay CI coverage. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
8f26138 to
aedbb69
Compare
|
Addressed both items in the review summary: retained ReplayFrameTooLarge now maps to the documented 409 resetRequired envelope, with no partial items or cursor. A live regression verifies reset, checkpoint/snapshot recovery, and subsequent replay. The PostgreSQL contention test now requires StepFailed and the exact lock-timeout diagnostic rather than accepting arbitrary errors. Six live replay tests and the enabled PostgreSQL unit suite passed (2,363 passed, 45 skipped). |
aedbb69 to
9e23fee
Compare
|
A focused follow-up on the PostgreSQL preparation concern found a concrete edge case: placeholder renumbering ran after inserting the quoted schema name, so legal '?' or quote characters in that identifier could be interpreted as SQL template syntax. Preparation now renumbers only the engine-owned template before substituting the quoted schema. The PostgreSQL journal regression uses a schema containing question-mark, double-quote and single-quote characters; it fails before the fix and passes afterward. All nine focused replay tests pass, including live PostgreSQL isolation/locking. Independent review found no additional actionable resource-lifetime or oversized-page reset issue; the existing reset-envelope/recovery coverage remains intact. |
9e23fee to
cf54421
Compare

Record change cursors now survive process restarts and work across servers sharing PostgreSQL. With
-Ddurable-realtime=true, built-in REST mutations write a bounded invalidation journal in the same transaction as the record; polling rechecks current authorization and returns opaque authenticated cursors scoped to each collection.Count, byte, frame, and retention limits bound journal storage. Expired cursors require reset; SQLite's existing local replay remains available. Direct SQL, Data API, and hook-side writes are outside this first capture boundary. Backup restore requires cursor-secret rotation, documented in the API guide.
Validation: enabled unit suite (2,358 passed, 44 skipped), live restart/rollback/privacy/expiry cases and two-server PostgreSQL replay, independent source and cryptography review, documentation/site checks, and a clean detached-commit gate. Both replay build flags compile together.
Stacked on #460; this PR adds durable replay only.