From 544c8bba0ec538784147247a58b862a7e2cd318e Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Thu, 4 Jun 2026 13:44:36 -0700 Subject: [PATCH] C2(hephd-self-update): impl systemd Restart=always for clean-exit respawn Self-restart works by exiting cleanly and letting the service manager respawn the new binary. launchd already does this (KeepAlive=true), but the systemd user unit was Restart=on-failure, which ignores a clean exit (code 0). Switch to Restart=always + RestartSec=1, update the unit test, and note in run-the-daemon that existing Linux installs must `heph daemon restart` once to regenerate the unit. Co-Authored-By: Claude Opus 4.8 (1M context) --- crates/heph/src/service.rs | 9 +++++++-- docs/how-to/run-the-daemon.md | 7 ++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/crates/heph/src/service.rs b/crates/heph/src/service.rs index 6015a3d..fc642a7 100644 --- a/crates/heph/src/service.rs +++ b/crates/heph/src/service.rs @@ -168,7 +168,8 @@ fn systemd_unit(hephd: &Path, db: &Path, socket: &Path) -> String { \n\ [Service]\n\ ExecStart={hephd} --mode local --db {db} --socket {socket}\n\ - Restart=on-failure\n\ + Restart=always\n\ + RestartSec=1\n\ \n\ [Install]\n\ WantedBy=default.target\n", @@ -400,7 +401,11 @@ mod tests { --db /home/e/.local/share/heph/heph.db \ --socket /run/user/1000/heph/hephd.sock" )); - assert!(unit.contains("Restart=on-failure")); + // Restart=always (not on-failure) so a clean exit (code 0) — what + // self-update does to hand off to the new binary — is respawned too. + assert!(unit.contains("Restart=always")); + assert!(!unit.contains("Restart=on-failure")); + assert!(unit.contains("RestartSec=")); assert!(unit.contains("WantedBy=default.target")); } diff --git a/docs/how-to/run-the-daemon.md b/docs/how-to/run-the-daemon.md index 8ada221..658a664 100644 --- a/docs/how-to/run-the-daemon.md +++ b/docs/how-to/run-the-daemon.md @@ -28,9 +28,14 @@ when it's already stopped is fine. `~/Library/LaunchAgents/org.hephaestus.hephd.plist`, with `RunAtLoad` + `KeepAlive` (starts at login, restarts if it crashes). - **Linux** — a **systemd user service** (`heph.service`) at - `~/.config/systemd/user/heph.service`, with `Restart=on-failure`, enabled for + `~/.config/systemd/user/heph.service`, with `Restart=always`, enabled for login. +> **Upgrading from an older install:** earlier units used `Restart=on-failure`, +> which does **not** respawn after a clean exit — so opt-in self-update (which +> exits cleanly to hand off to the new binary) wouldn't come back on Linux. Run +> `heph daemon restart` once (it regenerates the unit) to pick up `Restart=always`. + Either way it runs `hephd --mode local` against the default store (`~/.local/share/heph/heph.db`) and socket, with logs at `~/.local/share/heph/hephd.log`.