Skip to content

fix: keep stalled clients from wedging session attach#399

Open
crystal150 wants to merge 1 commit into
shell-pool:masterfrom
Humelo:fix/stalled-client-output
Open

fix: keep stalled clients from wedging session attach#399
crystal150 wants to merge 1 commit into
shell-pool:masterfrom
Humelo:fix/stalled-client-output

Conversation

@crystal150

Copy link
Copy Markdown

Issue Link

Fixes #335

AI Policy Ack

I read the AI policy and am disclosing AI use. The implementation and regression test were mostly AI-generated under user direction, then reviewed against the daemon control flow and validated with the full test suite and Clippy.

This PR was:

  • mostly or completely vibe coded
  • mostly or completely meat coded
  • bit of both

Description

A client that stops consuming terminal output can fill the Unix socket and block the long-lived shell->client thread inside write_all. That same thread owns attach, detach, resize, and heartbeat control messages, so subsequent attach attempts time out even though the PTY child continues running.

This change:

  • moves client socket writes to a dedicated writer thread behind a bounded queue;
  • keeps PTY spooling and session control responsive while a client write is blocked;
  • shuts down only the stalled client when the bounded queue fills, preserving the shell process and restore spool;
  • uses a short bounded drain barrier for clean detach exit-status delivery; and
  • adds a deterministic regression test that pauses the writer, floods output, verifies the child continues, and reattaches before releasing the stalled writer.

Verification

  • cargo test --all-features --quiet -- --skip prompt_prefix_zsh
    • all runnable tests passed; the skipped test requires /usr/bin/zsh, which is absent on the local host
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo fmt --all -- --check
  • targeted stalled-output regression and clean keybinding-detach regression both pass

@google-cla

google-cla Bot commented Jul 10, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@ethanpailes ethanpailes left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the patch and bug report!

I don't think we can consider this a fix for #335 without confirmation from the original reporter that it fixes their issue when they patch it in.

I don't like the extra sink thread approach taking in this patch. shpool already uses more threads than I would like for each session and I would like to avoid adding yet another one. Instead, I think the right approach is to use non-blocking IO and an overflow buffer with a max size limit that causes us to hang up when we reach the limit.

}
}

fn flush(&mut self) -> io::Result<()> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is lying. flush must not return before the data is actually written to the file descriptor and flushed.

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.

shpool attach returns immediately with status code 1 and no output

2 participants