Request reset cannot be observed independently while body polling is paused
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 890
- Forks
- 136
- Avg merge
- 14d 20h
- Merged PRs (30d)
- 2
Description
Version
h3 0.0.8, h3-quinn 0.0.10
Platform
Linux desktop 7.1.7 NixOS x86_64 GNU/Linux
Summary
Request reset is invisible while body polling is paused by application backpressure
Code Sample
let (body_tx, mut body_rx) = tokio::sync::mpsc::channel::<Bytes>(1);
// Fill the bounded application queue and stop consuming it.
body_tx.send(Bytes::from_static(b"first")).await?;
let reserve = body_tx.reserve();
tokio::pin!(reserve);
// Client now RESET_STREAMs the request body.
client.reset_request(STREAM_CANCEL_CODE)?;
// The server waits for application capacity and intentionally does not call
// recv.poll_data(). The h3 API has no separate reset event to select here.
assert!(tokio::time::timeout(Duration::from_millis(250), &mut reserve)
.await
.is_err());
Once the queue is drained and poll_data() resumes, h3 can return StreamErrorIncoming::StreamTerminated; the delayed visibility is the issue.
Expected Behavior
Request-stream reset should be independently observable even when body delivery is paused, allowing server work and buffered application state for that RPC to be cancelled promptly.
Actual Behavior
A peer RESET_STREAM is surfaced as StreamErrorIncoming::StreamTerminated only when the receive stream is polled. If an application has paused body polling because its bounded downstream channel is full, h3 exposes no independent per-stream reset future to select alongside that application backpressure.
Polling whole-connection closure does not solve this: a stream reset is intentionally local to one stream and does not close the QUIC connection.
Suggested upstream fix
Expose stream reset/closure as an independently pollable event, or define a split receive abstraction where body data and terminal/reset state can be driven without competing for the same mutable polling operation.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the supplied Tokio reproduction with a bounded channel, paused body polling, and client.reset_request(STREAM_CANCEL_CODE). Trace how recv.poll_data() produces StreamErrorIncoming::StreamTerminated and assess the proposed split or independently pollable reset event; done means a server can observe the per-stream reset while application backpressure still blocks body delivery.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend-api-design, networking
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100