M2: notebook read-replica (aco.ro.duckdb) to decouple readers from writers #510
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Decouple long-running notebook readers from batch writers: after each ingest,
publish a read-only snapshot
aco.ro.duckdband point notebooks /conf.connect.duckdb(read_only=True)at the replica. Writers own the primary;notebooks never block them. Staleness is bounded by the refresh cadence.
Scope
EXPORT/ATTACH+COPY).confswitch so notebook reads resolve to the replica.Background & alternatives:
docs/superpowers/specs/2026-07-08-duckdb-concurrency-streaming.md(option C). Complements the per-domain split(M2 / #D).
Implemented in
579d17beb4and live in prod:conf.connect.publish_replica("aco")— holds the write lock,CHECKPOINTs the WAL, copies todata/aco.ro.duckdb, swaps atomically. Wired as the final step ofingest_opps.pyandingest_asp.py, so staleness is bounded by ingest cadence (the issue's "refresh cadence").conf.connect.duckdb()read-only opens now resolve to the replica when it exists — notebooks never hold the primary's single-writer lock. Opt-outs:replica=FalseorSTACK_DUCKDB_REPLICA=0; write opens always use the primary.docs/docs/duckdb-concurrency.md(cadence, manual refresh one-liner, opt-outs, swap semantics).Verified live: replica published (3.1 GB) and the notebooks container resolves
conf.connect.duckdb()to/home/kert/data/aco.ro.duckdbwith current data visible. 82 conf tests cover snapshot consistency, divergence visibility, opt-outs, and atomic republish. Writers and notebook readers are now fully decoupled — the lock class of ingest failures is gone in day-to-day use; #511–#514 remain for the storage-level redesign.