Replies: 3 comments 1 reply
|
Thanks for testing and the report! We'll get on this |
|
Thanks again for the excellent report and repro — I dug into this and can confirm exactly what you saw. The good news: upgrading to v2.17.0 fixes the core bug. Root cause: in 2.16.0, the supervisor never loaded This was fixed in v2.17.0 (#585 changed the supervisor to load persisted state on startup) — though it landed inside a test-infrastructure PR, so the changelog doesn't call it out. I verified your exact repro against 2.17.0: after Follow-ups in flight:
Thanks for the detailed writeup — it made this straightforward to track down. This comment was generated by Claude Code. |
|
Follow-ups are up:
This comment was generated by Claude Code. |
Uh oh!
There was an error while loading. Please reload this page.
While evaluating pitchfork (installed via mise) I tested what happens to daemons when the supervisor crashes, and found that a crash orphans running daemons, and a subsequently restarted supervisor neither re-adopts nor kills them — so a later
pitchfork startruns a duplicate instance alongside the still-running orphan.Environment: pitchfork 2.16.0, macOS (arm64), installed via
mise use -g pitchfork.Repro:
pitchfork.tomlwith a trivial daemon:pitchfork start heartbeat— daemon runs as a direct child of the supervisor.kill -9 <supervisor pid>(simulating a supervisor crash/panic).PR_SET_PDEATHSIGequivalent.state.tomlstill has the correct record from before the crash (pid = <orphan pid>,status = "running"), and that pid is alive — butpitchfork listreports the daemon asavailable.pitchfork start heartbeat→ starts a second instance. Both processes now run concurrently (verified: both appending to the same log).Expected (or at least hoped): on startup, the supervisor could consult the persisted state — it already records pid, status, and the command — and for each daemon marked
runningwith a live pid either re-adopt it (resume monitoring) or, if adoption isn't feasible, stop the orphan before considering the daemon startable. Either would prevent the silent-duplicate outcome; today the stale-but-accurate state entry is discarded.For contrast, the graceful path is clean:
pitchfork supervisor stoptakes its child daemons down with it, and normal restarts leave nothing behind. This only bites on a genuine crash.Happy to provide more detail or test a fix. And thanks for pitchfork — the mise integration and the cron
retrigger = "always"semantics are exactly what I needed to replace a hand-rolled supervisor.All reactions