Repository navigation
feat(logger): keep session records on the card - #164
Merged
Merged
Conversation
Stage A left the record in RAM, so a driver's sessions were gone the moment the device lost power. They are appended to the card now, and read back at boot, so Review opens on the last session driven rather than on nothing. One file of fixed-size framed records rather than a directory per session: this is the Review index, and the per-session logs #38 will write are a separate thing. Each frame carries its own magic, version, length and checksum, which is what makes a card pulled mid-write cost only the record being written. A corrupt frame in the middle is stepped over rather than stopping the read. Stopping at the first bad frame is the obvious implementation and it throws away good sessions to protect a bad one; because frames are a fixed size, the reader can step to the next boundary and recover everything after the damage. The card is never assumed to be there. A failed write costs the durability of one record and nothing else - the cache takes it first, so Review shows the session either way. Losing the timer because a card misbehaved would be far the worse failure, and this is the subsystem that has never run on this device while a receiver is about to land on top of it at 25 Hz. Because the card mounts through VFS, the store uses plain stdio and the host tests exercise the real write path rather than a mock: a reopen, a frame truncated mid-record as an interrupted write leaves it, a byte flipped inside a middle frame, a path that cannot be opened at all, and a file longer than memory where the window has to seek to a frame boundary to avoid starting halfway through a record. The payload is the record's bytes, which makes the file device-internal rather than a portable export. Human-readable session output belongs with the per-session logs, and a field-by-field codec would buy portability nothing needs yet. Part of #137 and #38 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #137 and #38. Stage B of the session record: it survives the power cycle.
What it does
Session summaries are appended to
/sdcard/sessions.binand read back at boot, so Reviewopens on the last session driven rather than on nothing.
One file of fixed-size framed records — magic, version, length, checksum each — rather
than a directory per session. This is the Review index; the per-session logs #38 will write
are a separate thing.
The design decision worth reviewing
A corrupt frame in the middle is stepped over, not treated as end-of-file. Stopping at the
first bad frame is the obvious implementation, and it throws away good sessions to protect a
bad one. Because frames are a fixed size, the reader steps to the next boundary and recovers
everything after the damage. There's a test that flips a byte inside the middle of three
records and asserts the third still comes back.
The card is never assumed to be there. The cache takes the record first, so a failed write
costs the durability of that record and nothing else — Review shows the session either way.
Losing the timer because a card misbehaved would be far the worse failure.
Host tests hit the real write path
The card mounts through VFS, so the store uses plain stdio — meaning these tests exercise the
actual code that runs on device, against real files:
That last one matters: seeking a fixed offset back from the end would start halfway through a
record and lose the newest session to a misalignment.
Verified on device, and what is not
Boot on the real card is clean:
open=1isno_file— correct for a card with no sessions yet.The end-to-end durability claim is not yet confirmed on hardware. Recording a session and
reading it back after a real power cycle needs someone to press START and pull the plug, and
that has not been done. The logic is covered by the host tests against real files, and the
store opens correctly on the device, but the full loop on the physical card is untested. Worth
doing before this is relied on at a circuit.
38 host suites, 70 simulator tests.
A trade I made rather than an oversight
The payload is the record's bytes, so the file is device-internal, not a portable export —
a host tool cannot assume the layout. Human-readable session output belongs with the
per-session logs, and a field-by-field codec would buy portability nothing needs yet. Easy to
revisit if reading sessions off the card on a laptop becomes wanted sooner.