feat(dev-dump): record UDP for fm/f1, graceful shutdown, docs#58
Merged
feat(dev-dump): record UDP for fm/f1, graceful shutdown, docs#58
Conversation
dev:dump:fm and dev:dump:f1 previously only set a recordingGameId flag
that went unused — no .bin was produced. Wire a UdpRecorder into the
listener so these scripts now append raw datagrams to
test/artifacts/laps/{gameId}-{timestamp}.bin, matching the file layout
the shared-memory recorders (acc, ac-evo) already use.
Recording is additive: writePacket(buf) runs before parsePacket, so
live lap detection, DB writes, and WebSocket broadcasts to the
dashboard all keep working during a recording session. The /dev import
route auto-detects the gameId from the filename prefix and feeds the
dump through the full pipeline.
New docs/dev-recordings.md covers the end-to-end flow — which script
to run per game, where the .bin lands, and how to replay it via the
/dev Import Dump panel or the API.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Match the AccSharedMemoryReader pattern — pin recordingGameId once before start(), let the listener open its .bin implicitly instead of exposing a separate startRecording() toggle. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All three recorders (UDP, ACC, AC-Evo) buffer writes through Bun.file().writer(). Without a signal handler the default Ctrl+C path exits before the buffer drains and .bin files end up zero-length or tail-truncated. Install a graceful-shutdown handler whenever recordingGameId is set — it awaits stop() on every recorder in parallel before process.exit so the file has a clean tail. Also make UdpListener.stop() async and have restart() await it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Committed fixtures are the gzipped ones — raw .bin files from `dev:dump:*` runs are developer-local. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Raw .bin dumps are gitignored — document the gzip -k flow so contributors know how to land a new regression fixture. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Small bun script that walks test/artifacts/laps/ (or a single path) and gzips every raw .bin in place, keeping the original next to the .gz. Doc updated to point at the script. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Committing a recording should be deliberate — the script now errors without a path argument instead of sweeping every raw .bin in the default dir. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- parseDump takes (gameId, path) not just path — fix example - Ctrl+C now flushes via SIGINT handler, update tip accordingly - Dev URL is http://localhost:5173 (no portless/TLS) - Rename gzip:recordings -> gzip:recording to match single-file scope Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ss --no-tls) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e spawning server + vite - scripts/dev-proxy.ts: add --port 1355 so portless doesn't try to bind port 80 and request sudo - package.json dev script: run dev:proxy sequentially before the concurrent server + vite pair, matching the dev:dump:* pattern Co-Authored-By: Claude Opus 4.7 (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.
Summary
dev:dump:fm/dev:dump:f1now actually produce.binfiles. Previously they set arecordingGameIdflag that went unused — wire aUdpRecorderinto the listener so raw datagrams get appended, same directory and naming convention as the shared-memory recorders already use.SIGINT/SIGTERMhandlers flush all three recorders (UDP, ACC, AC-Evo) beforeprocess.exitsoCtrl+Cproduces a complete file instead of a zero-length one (Bun.file().writer()buffers internally).bun run gzip:recordings <path>script — gzips a single.binin place (raw.binis gitignored; commit the.bin.gzas a fixture).docs/dev-recordings.mdcovers which script runs for which game, where files land, how to commit a recording as a fixture, and how to replay via the/devimport panel.Test plan
bun run buildcleanbun run dev:dump:fmwith FM sending UDP →test/artifacts/laps/fm-2023-*.binexists, non-empty, Ctrl+C prints[UdpRecorder] Stopped. N packets written.bininto the/devImport Dump panel → detectsfm-2023, reports lap countdev:dump:f1bun run gzip:recordings path/to/foo.bin→ producesfoo.bin.gznext to it, keeps the raw🤖 Generated with Claude Code