Skip to content

[bug]: chat-daemon-daemon ignores SIGTERM, must SIGKILL — orphan daemons accumulate #1

@JamesHeal

Description

@JamesHeal

What happened?

cc-connect chat-daemon-daemon does not terminate on SIGTERM — it must be SIGKILL-ed. The sibling cc-connect host-bg-daemon does terminate cleanly on SIGTERM (its atexit / signal handler unlinks state and exits). The chat side appears to block somewhere in its cleanup path.

User-visible consequence: every time you close a TUI tab (or the TUI itself crashes / is force-quit) the chat-daemon for that room is left running. Over a few hours of normal use we accumulated 9 orphan chat-daemon-daemon processes (3h+ old at the top of the list) plus their stale ${TMPDIR}/cc-connect-${UID}/active-rooms/<topic>.active files. The hook's PID-liveness sweep can't help here because the orphan process is still alive — it just shouldn't be.

Reproduction

  1. cc-connect room start (spawns chat-daemon-daemon + host-bg-daemon).
  2. kill <chat-daemon-pid> (SIGTERM).
  3. ps -p <chat-daemon-pid> — process still running.
  4. kill <host-bg-pid> (SIGTERM) on the same room — that one does exit.
  5. kill -9 <chat-daemon-pid> — finally gone.

Reproduced today on main @ `be51e41` — sent SIGTERM to 16 daemons, 7 host-bg exited, 9 chat-daemon survived; SIGKILL cleaned them up.

cc-connect doctor output

```shell
[OK] identity.key at /Users/yijian/.cc-connect/identity.key is mode 0600
[OK] /var/folders/b_/lblpdcts7l13p015ws2145y80000gn/T/cc-connect-501/active-rooms is a directory with mode 0700
[OK] hook binary /Users/yijian/work/cc-connect/target/release/cc-connect-hook exists and is executable
[OK] mcp server /Users/yijian/.local/bin/cc-connect-mcp exists and is executable (registered in /Users/yijian/.claude.json)
[--] if Claude Code says 'cc-connect MCP not found' even though this check passed, restart Claude Code so it re-reads its config on launch.

4 ok, 0 warn, 0 fail
```

cc-connect version / commit

`v0.4.2-alpha-18-gbe51e41` (HEAD of `main`, commit `be51e41`)

rustc version

`rustc 1.95.0 (59807616e 2026-04-14)`

Operating system

macOS (Apple Silicon) — Darwin 24.6.0

Anything else?

Hypothesis (not yet confirmed by code read): the chat-daemon's shutdown path likely awaits one of:

  • gossip-topic leave ack from the iroh runtime,
  • IPC `accept()` loop on `chat.sock` finishing,
  • chat_session worker tasks draining,

and one of those is not signal-aware. host-bg-daemon doesn't have the IPC socket or chat_session, which is consistent with it shutting down clean.

Suggested fix direction: install a tokio `signal::ctrl_c` / unix-signal listener that flips a shutdown `CancellationToken`; thread the token into the IPC accept loop and any blocking wait in chat_session so they bail. Then the existing `atexit` unlink of `.active` runs as a normal exit path.

Related UX impact: `Ctrl-W` close-tab in the TUI presumably already SIGTERMs the daemon (per the README's "prompts whether to also stop the daemon"); if so, choosing "yes, stop the daemon" silently does nothing and the daemon survives. Worth verifying as part of the fix.

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions