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§
- Oplog
Journal - Append-only JSONL journal for
OpRecords. Holds an exclusive advisory lock on<path>.lockfor its lifetime — one writer per journal path. - Truncation
Marker - 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 byOplogJournal::load_with_marker; fencesOplogJournal::load.