fix: lifecycle cleanup — graceful HTTP shutdown + mount leyline teardown#126
Merged
jamestexas merged 2 commits intomainfrom Mar 23, 2026
Merged
fix: lifecycle cleanup — graceful HTTP shutdown + mount leyline teardown#126jamestexas merged 2 commits intomainfrom
jamestexas merged 2 commits intomainfrom
Conversation
- 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
There was a problem hiding this comment.
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 withhttp.Server.Shutdown(10s timeout) and treatshttp.ErrServerClosedas a clean exit. - Keeps stdio-mode hard exit behavior (no HTTP server to drain).
- Adds
defer leyline.StopManaged()tomache mountso 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.
… 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.
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
os.Exit(0)which skipped defers (registry.Close,removeServeSidecar,StopManaged) and didn't drain in-flight requests. Replaced withhttpSrv.Shutdown(ctx)— signal now gracefully drains connections (10s timeout),ListenAndServereturnsErrServerClosed, and all defers run normally. Stdio mode keeps hard exit (no HTTP server to drain).mount.gofiresleyline.TriggerEmbeddingwhich can auto-spawn a managed daemon viaDiscoverOrStart, but never cleaned it up. Addeddefer leyline.StopManaged()so the daemon is stopped when the mount exits.embedOncepattern inlazyGraph.get()— trigger only fires after graph init completes. Closed as already-resolved.Test plan
task buildsucceedstask test— all tests passmache serve .→ Ctrl-C → verify "shutting down…" log + clean exit (no orphaned leyline)mache mount .→ Ctrl-C → verify no orphaned leyline process after unmount🤖 Generated with Claude Code