Repository navigation
gateway: allowance stays fail-closed on a partial snapshot; atomic snapshot rebuild (D257) - #119
Merged
Merged
Conversation
… snapshot rebuild (D257)
A rebuild removed the snapshot, appended Puts, and wrote the cursor last, in
place. A crash midway left some Puts and no cursor; the next boot with NATS
down installed them as a READY allowance-set holding only part of the
exhausted tenants, so the rest were served and /readyz said 200.
- WatchedSet::SEED_FROM_CURSORLESS_SNAPSHOT: deny (fail-open) still seeds from
any snapshot; allowance (fail-closed) seeds only from one with a cursor
record, decided before anything is installed or the ready gauge flips.
- rebuild_snapshot writes {path}.tmp, fsyncs it, renames over path, fsyncs
the directory, and reopens path for appends. A stale .tmp is removed first;
any failure aborts to snapshot-less.
- beyond-slipstream 0.1.0 -> 0.8.0 (same v2 on-disk format, API compatible).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JimHGjsfk2Ktm5GxyZJKKk
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JimHGjsfk2Ktm5GxyZJKKk
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.
Summary
D257 (Reliability/Security, med).
rebuild_snapshotremoved the file, appendedPuts, and wrote the cursor last, all in place. A crash midway left somePuts and no cursor. The next boot with NATS unreachable installed that file as a ready allowance-set holding only part of the exhausted tenants: the rest were served, and/readyzreturned 200.WatchedSet::SEED_FROM_CURSORLESS_SNAPSHOT. Deny (fail-open) still seeds from any snapshot. Allowance (fail-closed) seeds only from a snapshot that has a cursor record, and this is decided before the slot or the ready gauge is touched. Only a revision > 0 cursor skips the scan on connect, same as before.is_resumable. That made an edge gateway with an empty allowance bucket (empty scan, cursor revision 0) unready with NATS down, and the existing e2eon_disk_snapshot_enforces_across_restart_without_natsfailed. Every writer puts the cursor after the data it covers, so a cursor record of any revision proves the read was complete.{path}.tmp, fsyncs it, renames it overpath, fsyncs the directory, and reopenspathfor appends. It removes any stale.tmpfirst, and any failure (removal or rename) aborts to snapshot-less mode.compact_to_fileis private), so the temp-file-and-rename lives here.Test plan
reliability_snapshot.rs(hermetic, NATS on a closed port):/readyz503;load()returns the previous complete snapshot with its cursor;.tmpis discarded, and the reopened writer appends to the renamed file.true, the fail-closed test fails (402 served).cargo nextest run -p beyond-ai: 1093/1093 passed.cargo clippy --all-targets -D warnings,cargo fmt --check,dprint checkandverify gate(static) all pass.🤖 Generated with Claude Code
https://claude.ai/code/session_01JimHGjsfk2Ktm5GxyZJKKk