Skip to content

mu-ad5x serve: abort the presence task on shutdown — mu serve hung after stdin close#490

Merged
sahuagin merged 1 commit into
mainfrom
cc/mu-ad5x-presence-shutdown
Jul 14, 2026
Merged

mu-ad5x serve: abort the presence task on shutdown — mu serve hung after stdin close#490
sahuagin merged 1 commit into
mainfrom
cc/mu-ad5x-presence-shutdown

Conversation

@tcovert-c137

@tcovert-c137 tcovert-c137 Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Fixes mu-ad5x: since the etcd-lease presence merge (949fed77), mu serve never exits after stdin closes on any box where etcd is reachable — including the serve child under mu solo. Repro: just smoke completes the ask, logs dialogue presence: lease-registered, then hangs until the recipe's 5s guard kills it; one commit earlier it exits cleanly.

Root cause

presence::spawn starts an infinite reconcile loop (lease keepalive/re-grant + peer-key reconcile every ttl/3) holding a Sessions clone, and drops the JoinHandle. mu's shutdown is reference-driven — serve's exit waits on session channels closing — so the immortal clone wedges the documented shutdown cascade. serve/mod.rs already names this exact hazard and solves it for the MCP listener ("transport::serve's shutdown cascade … deadlocks if any external clone keeps those alive. AbortOnDrop is captured by the handler closure…"); the presence task was the one spawn without the guard.

Change

  • presence::spawn returns its JoinHandle, marked #[must_use = "tie this handle to shutdown (AbortOnDrop) or serve never exits (mu-ad5x)"] so the omission can't silently recur.
  • serve wraps it in AbortOnDrop captured by the transport closure, exactly like mcp_guard: dropping the handler aborts the task and releases its Sessions clone, letting the cascade complete.

Aborting is crash-equivalent and safe by the lease design: the etcd lease expires at TTL and the peer keys vanish with it — the same cleanup a daemon crash gets. No graceful revoke needed.

Verification

On this box (etcd reachable, presence active): just smoke now logs lease-registered, answers, and exits cleanly (exit 0) where it previously hung to the kill guard. Full just ci-aipr green.

Gate

pre-pr-check green; consensus panel PASS — unanimous approve in 1 round, all four (focused) seats live.

🤖 Generated with Claude Code

https://claude.ai/code/session_01REB3QZvP3arA2cLMVRgYam

…ter stdin close

The etcd-lease presence task (lyksmpsp) is an infinite reconcile loop
holding a Sessions clone, spawned with its JoinHandle dropped. mu's
shutdown is reference-driven — serve's exit waits on session channels
closing — so on any box where etcd is reachable the task kept every
session alive forever and `mu serve` never exited after stdin closed
(observed: just smoke killed at its 5s guard on a clean change atop
lyksmpsp; clean exit one commit earlier).

Apply the file's own established pattern for exactly this hazard (the
MCP listener's AbortOnDrop): presence::spawn now returns its JoinHandle
(#[must_use]), and serve wraps it in AbortOnDrop captured by the
transport closure — dropping the handler aborts the task and releases
its Sessions clone, letting the documented shutdown cascade complete.

Aborting is crash-equivalent and safe by the lease design: the etcd
lease expires at TTL and the peer keys vanish with it — the same
cleanup a daemon crash gets.

Verified on this box (etcd reachable, presence active): just smoke now
completes AND mu serve exits cleanly (previously killed at the 5s
guard); lease-registered still logged, ask unaffected.
@sahuagin sahuagin merged commit c00c437 into main Jul 14, 2026
5 checks passed
@sahuagin sahuagin deleted the cc/mu-ad5x-presence-shutdown branch July 14, 2026 18:28
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.

1 participant