Closed Haplo79 closed 1 year ago
Thanks for the report! I agree that this looks fishy. New flow control credit should be issued after both peers drop their handles to the stream. Can you share a complete runnable repro?
@Ralith Let me know if the attached source counts as a runnable repro. I'm not quite sure the best way to share that in a forum like this, maybe I should create a repo?
That's perfect, thanks! Behavior is as described. I'll investigate this week.
This turned out to be pretty simple. The I/O on the connection is not specifically significant: the issue is that we don't immediately update stream ID flow control when a stream that has been stopped is reset. Do you want a backport for 0.8?
As to backport - am prepared to jump on .9 as soon as its released, and that would probably be the best way to get this fix. If .9 is more than a couple of weeks away, I certainly would not refuse a backport if its easy. :) Thanks.
Scenario (run on loopback):
Server
Client
A client limited to one uni-stream (max_concurrent_uni_streams(1u32.into()) tries to open uni-streams to the server in a loop:
async fn create_stream_and_write(connection: quinn::Connection) -> anyhow::Result<()> { println!("creating new stream"); let mut uni = connection.open_uni().await?; println!("new stream created");
}
async fn writes(uni: &mut quinn::SendStream) -> anyhow::Result<()> { for _ in 0..500 { println!("writing"); uni.write_u8(245).await.context("write failure")?; }
}
Notes: