Skip to content

fix: lifecycle cleanup — graceful HTTP shutdown + mount leyline teardown#126

Merged
jamestexas merged 2 commits intomainfrom
fix/p1-lifecycle-cleanup
Mar 23, 2026
Merged

fix: lifecycle cleanup — graceful HTTP shutdown + mount leyline teardown#126
jamestexas merged 2 commits intomainfrom
fix/p1-lifecycle-cleanup

Conversation

@jamestexas
Copy link
Copy Markdown
Contributor

Summary

  • mache-5c6836: HTTP mode signal handler used os.Exit(0) which skipped defers (registry.Close, removeServeSidecar, StopManaged) and didn't drain in-flight requests. Replaced with httpSrv.Shutdown(ctx) — signal now gracefully drains connections (10s timeout), ListenAndServe returns ErrServerClosed, and all defers run normally. Stdio mode keeps hard exit (no HTTP server to drain).
  • mache-5c6f1b: mount.go fires leyline.TriggerEmbedding which can auto-spawn a managed daemon via DiscoverOrStart, but never cleaned it up. Added defer leyline.StopManaged() so the daemon is stopped when the mount exits.
  • mache-912a77: Embed trigger race was already fixed by the embedOnce pattern in lazyGraph.get() — trigger only fires after graph init completes. Closed as already-resolved.

Test plan

  • task build succeeds
  • task test — all tests pass
  • Manual: mache serve . → Ctrl-C → verify "shutting down…" log + clean exit (no orphaned leyline)
  • Manual: mache mount . → Ctrl-C → verify no orphaned leyline process after unmount

🤖 Generated with Claude Code

- serve.go HTTP mode: replace os.Exit(0) signal handler with
  httpSrv.Shutdown(ctx) so in-flight requests drain and defers
  (registry.Close, StopManaged, removeServeSidecar) run normally.
  Stdio mode keeps hard exit since there's no HTTP server to drain.

- mount.go: add defer leyline.StopManaged() before TriggerEmbedding
  so auto-spawned leyline daemons are cleaned up when the mount exits.

- Closes mache-912a77 (embed race): already fixed by embedOnce in
  lazyGraph.get() — trigger fires only after graph is materialized.

Closes: mache-5c6836, mache-5c6f1b, mache-912a77
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves lifecycle cleanup around mache serve and mache mount by ensuring auto-started Leyline daemons are stopped and HTTP serving mode shuts down gracefully so defers execute and in-flight requests are drained.

Changes:

  • Replaces HTTP-mode hard os.Exit(0) signal handling with http.Server.Shutdown (10s timeout) and treats http.ErrServerClosed as a clean exit.
  • Keeps stdio-mode hard exit behavior (no HTTP server to drain).
  • Adds defer leyline.StopManaged() to mache mount so any auto-spawned Leyline daemon is torn down when the mount exits.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
cmd/serve.go Implements graceful HTTP shutdown on SIGINT/SIGTERM while preserving stdio hard-exit behavior; ensures defers run in HTTP mode.
cmd/mount.go Ensures any auto-started Leyline managed daemon is stopped when the mount command exits.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cmd/serve.go
… exit

Copilot review: signal.Notify without signal.Stop leaks the notification
goroutine if ListenAndServe returns for a non-signal reason (bind error).
signal.NotifyContext + defer sigStop() handles both paths cleanly.
@jamestexas jamestexas merged commit 0070d77 into main Mar 23, 2026
14 checks passed
@jamestexas jamestexas deleted the fix/p1-lifecycle-cleanup branch March 23, 2026 23:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants