Skip to main content

Module journal

Module journal 

Source
Expand description

Durable JSONL persistence for the oplog — the car-eventlog journal idiom: append-only, one record per line, torn-line tolerant on load.

A crash mid-write leaves at most one torn (unparseable) trailing line; OplogJournal::load skips it (and any blank lines) instead of failing, exactly like EventLog::load. Nothing is lost from the sync’s point of view: an op that never fully reached the journal was never acked, and the oplog’s convergence is defined over the op-set — re-appending it (or re-pulling it from a peer/relay in B3) folds to the same state. Integrity/order checking is deliberately NOT done here — it is the explicit, separate crate::oplog::verify_log pass.

Single writer, enforced. A journal is one device’s log: two writers on one path would fork the seq chain and can interleave bytes mid-record. OplogJournal::open therefore takes an exclusive advisory lock on <path>.lock (held for the journal’s lifetime; the OS releases it on drop) and fails with WouldBlock if another holder exists — the same protocol car-registry’s supervisor uses for agents.json.lock. OplogJournal::load is read-only and takes no lock.

Truncated journals are marked and fenced (B4). OplogJournal::truncate_to stamps a TruncationMarker as the new file’s first line — atomic with the truncation itself (same rename, no crash window in between). The marker names the covering checkpoint’s content address, and it exists to make a permanent-fork hazard a runtime error instead of a documentation footnote: a device whose ops were ALL below the frontier leaves no trace of itself in the retained tail, so DeviceLog::resume over that tail would silently restart it at seq 0 — an unrecoverable duplicate-seq chain fork. Therefore OplogJournal::load refuses a marked journal (use OplogJournal::load_with_marker, fetch the named checkpoint, and go through crate::checkpoint::resume_anchored / crate::checkpoint::verify_anchored), and DeviceLog::resume itself rejects an own-chain non-zero start as a second fence.

Structs§

OplogJournal
Append-only JSONL journal for OpRecords. Holds an exclusive advisory lock on <path>.lock for its lifetime — one writer per journal path.
TruncationMarker
The first line of a truncated journal: names the checkpoint (by whole-record content address) that accounts for everything the truncation dropped. Written atomically WITH the truncation by OplogJournal::truncate_to; surfaced by OplogJournal::load_with_marker; fences OplogJournal::load.