-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
QUIC: Reuse QuicStream instances on a connection #49972
Comments
Tagging subscribers to this area: @dotnet/ncl Issue DetailsIn Kestrel we want to reduce per-request HTTP/3 connections to the minimum possible. Ideally that would be zero. With HTTP/1.1 and HTTP/2 Kestrel is able to reuse per-request instances. For example, after a HTTP/2 request is gracefully completed (i.e. wasn't aborted and finished writing a frame with the close stream bit set) the stream is returned to a pool on the connection. Future requests on the connection will reuse the pooled stream by reseting it back to its initial state instead of creating a new one. This is discussed in a blog post. At the moment a new QuicStream is created for each HTTP/3 request on a connection: public class QuicConnection
{
// Existing
QuicStream OpenUnidirectionalStream();
QuicStream OpenBidirectionalStream();
ValueTask<QuicStream> AcceptStreamAsync();
// New?
void ReturnCompletedStream(QuicStream stream);
} Support should be added to System.Net.Quic for optionally returning a QuicStream back to the connection when an app is no longer using it. The instance can then be reused by one of the factory methods above.
|
Triage: Leave it in Future, if it pops in perf analysis, we can move it to 7.0. |
Unlike a TCP stream, which is the connection, QUIC multiplexes streams over a single connection. |
That's how I understood the issue. I think it's highly unlikely msquic would support re-using their stream object, but maybe I'm wrong, @nibanks? |
MsQuic stream objects are highly optimized for creation and deletion (most of the time it's just pushing and popping from a pool list). So don't really need/want to support reuse. Now, if that's not easy to do in C#, perhaps you could support reuse by just deleting the old one and opening a new one. |
Yeah, I thought so, and since native memory doesn't influence GC, recreating the msquic object wouldn't have any negative impact on pooling our managed wrapper. |
We could add API that allows to assign new stream to existing |
In Kestrel we want to reduce per-request HTTP/3 allocations to the minimum possible. Ideally that would be zero.
With HTTP/1.1 and HTTP/2 Kestrel is able to reuse per-request instances. For example, after a HTTP/2 request is gracefully completed (i.e. wasn't aborted and finished writing a frame with the close stream bit set) the stream is returned to a pool on the connection. Future requests on the connection will reuse the pooled stream by reseting it back to its initial state instead of creating a new one. This is discussed in a blog post.
At the moment a new QuicStream is created for each HTTP/3 request on a connection:
Support should be added to System.Net.Quic for optionally returning a QuicStream back to the connection when an app is no longer using it. The instance can then be reused by one of the factory methods above.
Extra things to consider:
The text was updated successfully, but these errors were encountered: