Skip to content

fix(http1): drain client dispatch receiver on connection shutdown - #4222

Merged
seanmonstar merged 1 commit into
hyperium:masterfrom
akasakariko:fix/http1-dispatch-close-race
Oct 9, 2026
Merged

seanmonstar merged 1 commit into
hyperium:masterfrom
akasakariko:fix/http1-dispatch-close-race

Conversation

@akasakariko

Copy link
Copy Markdown
Contributor

Closes #4202

Summary

On HTTP/1 shutdown, tasks reserving channel capacity before close could publish afterward and leave envelopes stranded; this fix closes and asynchronously drains the dispatch receiver until Ready(None), canceling unsent requests with original requests recoverable while callers hold SendRequest or hyper-util

Changes:

  • src/proto/h1/dispatch.rs and src/client/dispatch.rs: close and drain dispatch receiver on shutdown until Ready(None)
  • Cache original connection result during drain to avoid polling closed IO again
  • Keep upgrade and CONNECT handoff behavior unchanged
  • Regression tests use Tokio budget exhaustion for reset, idle EOF, and dispatch driving without IO shutdown
  • Stranded callbacks reproduced separately with temporary reservation-splitting instrumentation; instrumentation excluded from commit

Verification

Local verification passed (GitHub CI not started):

  • cargo test --features full --lib client_close_drains_pending_requests: 3 pass with fix, 3 fail on original code; passes on Tokio 1.38.2
  • cargo test --features full: 315 passed, 10 ignored
  • rustfmt --check --edition 2021 $(git ls-files '*.rs') and git diff --check pass
  • cargo clippy --features full -- -D warnings: exits 0 with 3 pre-existing manifest warnings
  • cargo hack depth-2 powerset passes across 66 configurations including tracing
  • Rust 1.63.0 cargo check passes with MSRV-aware vendored dependencies
  • cargo semver-checks against origin/master: 223 checks pass
  • RUSTFLAGS='--cfg hyper_unstable_ffi' cargo test --features client,http1,http2,ffi --lib: 99 passed, 6 ignored

Keep the closed dispatch receiver alive until all in-progress sends have published and canceled their callbacks

Preserve the connection result across drain polls and keep upgrade handoffs unchanged

Closes hyperium#4202

@seanmonstar seanmonstar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks!

@seanmonstar
seanmonstar merged commit 97fff93 into hyperium:master Oct 9, 2026
23 checks passed
akasakariko added a commit to akasakariko/akasakariko that referenced this pull request Oct 10, 2026
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.

hyper-util legacy client: an HTTP/1 request can hang forever when the connection closes while the request is being queued

2 participants