-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
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:
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.
Extra things to consider:
- Validate QuicStream is in a valid state before pooling it.
- Maximum number of pooled streams. In Kestrel there is a max of 100 HTTP/2 pooled streams allowed on a connection. I don't think this needs to be configurable.
- Remove unused streams after a certain amount of time. In Kestrel the HTTP/2 pooled streams on a connection are removed if not used within a certain amount of time. In place so idle connections don't unnessarily hold onto memory. I don't think this needs to be configurable.