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.
Version
h3 0.0.8,h3-quinn 0.0.10Platform
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
Once the queue is drained and
poll_data()resumes, h3 can returnStreamErrorIncoming::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_STREAMis surfaced asStreamErrorIncoming::StreamTerminatedonly 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.