Skip to content

fix(daemon): reclaim serial sessions whose clients have all exited (#1429) - #1727

Merged
zackees merged 1 commit into
mainfrom
fix/1429-reclaim-dead-client-port
Oct 25, 2026
Merged

zackees merged 1 commit into
mainfrom
fix/1429-reclaim-dead-client-port

Conversation

@zackees

@zackees zackees commented Oct 25, 2026

Copy link
Copy Markdown
Member

Refs #1429. This is the issue's "request 1": reclaim a port lock when its owning client is gone.

Mechanism

SharedSerialManager::open_port publishes the session (OS fd open, owner_client_id set) before the client attaches a reader or writer. The only automatic close is close_port_after_grace_if_idle, which runs on reader/writer detach. So when a client dies after open_port but before attaching, or the WS attach times out, the session is left like this:

[HELD] open=true owner=<id> writer=none readers=0
  client <id> pid=… (dead)

That is exactly the fbuild daemon locks output in the issue. Nothing schedules a close for it, so every other opener gets EBUSY. A later generation bump can also cancel a pending grace close without rescheduling it.

Change

  • handlers::locks::reclaim_dead_client_serial_sessions closes a session only when every client it references (owner, writer, readers and the metadata entries) has a recorded pid and none of those processes is alive.
  • The daemon's existing maintenance loop runs it every 2 s (DEAD_CLIENT_SERIAL_RECLAIM_INTERVAL).
  • This is deliberately stricter than clear-locks --stale: a session with no readers or writer but a live or unknown-pid owner is kept, because that is the normal deploy → attach hand-off.

Verification

  • New tests:
    • a session whose clients are all dead is closed
    • live-pid and unknown-pid sessions are kept
    • a dead owner with a live second reader is kept
  • soldr cargo test -p fbuild-daemon (288 + 13 pass). Workspace clippy with -D warnings is clean.
  • Real pty check (socat): fbuild monitor held the port, then kill -9 on the CLI, and the port was released 2.2 s later. That release came from the existing WS-disconnect path, not this sweep, which confirms the normal path is unchanged. I could not reproduce the open-then-die-before-attach window without the reporter's two-device rig, so the new path is covered by unit tests only.

Not covered

The issue's "request 2" (timeout message naming the dead client) is not in this PR; open_port_timeout_message already names the holding process.

@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 43 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between 6530cb6 and 2abf5e8.

Files selected for processing: 3
  • crates/fbuild-daemon/src/context.rs
  • crates/fbuild-daemon/src/handlers/locks.rs
  • crates/fbuild-daemon/src/main.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

…1429)

A session is published by open_port before its client attaches a reader.
If that client dies in between (or the WS attach times out), the session is
left with an owner but no readers/writer, no idle close is scheduled, and the
port returns EBUSY to every other opener until something else closes it.
fbuild daemon locks already showed the owner as (dead).

Every 2s the daemon now closes sessions in which every known client has a
recorded pid and none of those processes is alive. Sessions with a live or
unknown-pid client are kept, so the deploy -> attach hand-off is untouched.
@zackees
zackees force-pushed the fix/1429-reclaim-dead-client-port branch from 78b4906 to 2abf5e8 Compare October 25, 2026 04:41
@zackees
zackees merged commit 325bb11 into main Oct 25, 2026
24 checks passed
@zackees
zackees deleted the fix/1429-reclaim-dead-client-port branch October 25, 2026 04:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant