Skip to content

fix(daemon): session-local daemon exits when its session is gone - #391

Draft
dotfyles wants to merge 3 commits into
mainfrom
fix/session-daemon-exit-when-session-gone
Draft

dotfyles wants to merge 3 commits into
mainfrom
fix/session-daemon-exit-when-session-gone

Conversation

@dotfyles

@dotfyles dotfyles commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Every Claude Code session starts wire mcp, which spawns a detached wire daemon --interval 5 in a session-keyed home (sessions/by-key/<hash>). Nothing ties that daemon's life to the session. When the session and its wire mcp exit, the daemon is reparented to init and polls forever (107 such daemons on one host). #378 bounds this only in supervisor mode (--all-sessions), which does not run here.

Fix

In the single-home daemon loop (src/cli/relay.rs), for by-key homes only, the daemon exits cleanly when ALL hold for 3+ consecutive ticks spanning 60s+:

  • state/wire/mcp.pid is missing or its pid is dead (on Linux a live pid whose cmdline lacks wire counts as reused);
  • relay state has 0 pinned peers;
  • outbox has nothing pending.

A returning mcp resets the counter. daemon.pid is removed by the existing DaemonPidGuard. Machine-default homes and supervisor mode are unchanged. WIRE_DAEMON_NO_ORPHAN_EXIT=1 disables the exit. Helpers and debounce live in src/ensure_up.rs.

Limitation: pid-reuse check is a cmdline heuristic on Linux only; mcp.pid records no process start time.

Tests

  • cargo build: ok
  • cargo test --lib ensure_up: 12 passed, 0 failed (includes new orphan_tracker_needs_ticks_and_time_and_resets)
  • cargo clippy -- -D warnings: not run, clippy not installed on this host
  • Not exercised: a live daemon actually exiting end to end.

Author model: claude sonnet

Review log

  • Author: claude sonnet
  • Reviewer: codex gpt-6.1-sol
  • Finding (pushed-log file kept session from ever being orphaned) fixed in b562d9e, with test.
  • Finding 2 (supervisor-managed workers orphan-exit and get respawned forever) fixed in de69290, with test.

🤖 Generated with Claude Code

`wire mcp` spawns a detached `wire daemon` in a by-key session home, but
nothing tied the daemon to the session: once the Claude session and its mcp
exited, the daemon was reparented to init and polled forever (107 of them on
one host). PR #378 bounds this only in supervisor mode.

In single-home mode, for by-key homes only, the daemon now exits cleanly
(daemon.pid removed by the existing guard) after 3+ consecutive ticks over
60s+ in which mcp.pid is missing/dead (or its pid was reused by a non-wire
process on Linux), the home has no pinned peers, and the outbox is empty. A
returning mcp resets the counter. Machine-default homes and supervisor mode
are unchanged. WIRE_DAEMON_NO_ORPHAN_EXIT=1 disables the exit.

Model: claude-sonnet (claude -p --model sonnet)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Deploying wireup-landing with  Cloudflare Pages  Cloudflare Pages

Latest commit: de69290
Status: ✅  Deploy successful!
Preview URL: https://f5f19b9a.wireup-landing.pages.dev
Branch Preview URL: https://fix-session-daemon-exit-when.wireup-landing.pages.dev

View logs

@coderabbitai

coderabbitai Bot commented Oct 25, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

dotfyles and others added 2 commits October 25, 2026 15:08
Successful delivery leaves <peer>.pushed.jsonl behind, so a dead session
with no peers never counted as orphaned. Only non-empty <peer>.jsonl
queue files count as pending outbound.

Model: claude-sonnet
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The supervisor respawns any worker that exits, so a by-key worker with no
MCP, no peers and an empty outbox looped exit/respawn every 60s. Gate the
orphan exit on WIRE_SUPERVISOR_MANAGED.

Model: claude-sonnet

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
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