feat(startup): configurable scene load on boot and save-on-quit - #63
Merged
Conversation
Add a rig-config `[startup]` section so a rig can boot into a known scene
with no client attached:
- `load_config` — a named config in the config dir, or "last" for the
auto-saved last-session slot; empty/omitted starts with an empty scene.
An explicit `--config <path>` still overrides it.
- `save_on_quit` — writes the current scene + VTL names to the last-session
slot on graceful shutdown, so `load_config = "last"` restores it next boot.
Save-on-quit locks scene-then-vtl to match the ZMQ thread's order, which is
still live during shutdown. A missing last-session slot on first boot is a
logged no-op, not an error.
Refactor for reuse/testability: extract `io_config::config_path` and
`LAST_SESSION_CONFIG`, and `SceneState::{load,save}_named_config` shared by
the LoadConfig command and the boot path.
Tests: rig_config startup parsing (named, "last" case-insensitive, empty,
unknown-field rejection) and a startup_config suite covering save/load
roundtrip, path layout, dir creation, not-found, and replace semantics.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H8SPHZX5iVSoKyJ7ZqRVtS
Spawn the real vstimd binary under --null, create a stimulus over ZMQ, send SIGTERM, and assert the last-session config is written with the scene content — exercising main.rs's shutdown path end to end. Complements the unit-level startup_config.rs tests. Also asserts nothing is written when save_on_quit is disabled. Linux-only (relies on the SIGTERM handler). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H8SPHZX5iVSoKyJ7ZqRVtS
Extends the startup save/load feature: - Quit-time save (save_on_quit) now writes TWO artifacts: it overwrites the _last_session slot AND writes a timestamped archive vstimd_<YYYYMMDDTHHMMSSZ>.config.json for history. Archives are never pruned; a warning is logged once >500 accumulate in one dir. The UTC timestamp is formatted with a small dependency-free civil-date helper (std has no datetime), with a note to switch to a crate if needs grow. - Config dir now defaults to /var/lib/braemons/vstimd for a deployed rig (packaged systemd unit sets StateDirectory=braemons/vstimd + --config-dir). When that isn't writable (e.g. a non-root dev run) it falls back to ~/.local/braemons/vstimd, then the current directory, logging the choice. An explicit --config-dir is still honoured verbatim. - Example rig configs (jetson-orin-nano, raspberry-pi-4/5) document the [startup] section, kept commented so they parse to no-load/no-save. Tests: dependency-free UTC formatter and archive-name recogniser (unit); config-dir writability + first-writable fallback and the two-artifact session snapshot (integration); the save-on-quit e2e now also asserts the timestamped archive; example configs are globbed through the real loader and checked to default startup off. Also ignore stray root vstimd_*.config.json. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H8SPHZX5iVSoKyJ7ZqRVtS
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
vstimd can now boot into a known scene with no client attached, controlled by a new rig-config
[startup]section:Behaviour
main.rs): after VTL init, an explicit--config <path>still wins; otherwise[startup] load_configapplies."last"(case-insensitive) resolves to a reserved slot (_last_session). A missing last-session slot on first boot is a logged no-op; a missing named config logs an error.main.rs): once the render loop returns (shutdown requested), the scene + VTL names are written to the last-session slot. Locks scene-then-vtl to match the ZMQ thread's order (ipc.rs), which is still live during shutdown — the reverse order would risk a deadlock mid-request.Refactors (reuse / testability)
io_config: newLAST_SESSION_CONFIGconstant andconfig_path(dir, name)— the single place thevstimd_<name>.config.jsonlayout lives (previously duplicated).SceneState::{load,save}_named_config— reusable methods shared by theLoadConfigcommand and the boot path.rig_config:StartupRigConfig+StartupLoadenum with a custom deserializer.Tests
server/tests/rig_config.rs: startup parsing (named,"last"incl. case-insensitivity, empty string, unknown-field rejection).server/tests/startup_config.rs(new): save→load roundtrip, expected file path, dir auto-creation, not-found reporting, last-session slot roundtrip, replace-clears-previous.Full
cargo testsuite green;cargo clippyclean (only a pre-existing unrelated warning). Smoke-tested against--null: first boot logs "no last-session config yet", writes the file on shutdown, second boot logs "loaded startup config '_last_session'". Docs updated insaving-loading.mdanddefault-rig-config.toml.🤖 Generated with Claude Code