dotnet / dotnet/aspnetcore

Performance optimizations for streams now that the WebTransport PR introduced new stream types

Open
#42,789 0 comments 1 reaction 0 assignees View on GitHub
area-networking HTTP3 Perf
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

### Is there an existing issue for this?

- [X] I have searched the existing issues

### Is your feature request related to a problem? Please describe the problem.

Due to the WebTransport PR adding support for unidirectional streams that are not control streams, Kestrel now must read the stream type from the stream header prior to classifying it and making a `Http3Stream` or `Http3ControlStream` instance for it. To still be able to track this stream, and enforce timeouts and other aborts, the PR introduced a new stream type, `Http3PendingStream`. This is a short-lived stream that fulfills this issue. It is a rather inefficient solution though as it increases the number of allocations and decreases the performance for all HTTP/3 stream requests.

### Describe the solution you'd like

There are multiple possible solutions. For example, we could pool the streams and then re-use them. However, perhaps the best solution would be to rethink how streams are defined. Perhaps the best solution would actually be to rewrite streams entirely so that they follow a decorator pattern or something similar. That way we can add functionality as we identify the stream rather than having to create new objects as we go along.

This would also have the added benefit of deduplicating shared code between stream types. Currently, there is quite a bit of it, and it is quite hard to remove, as I found out when I tried to do something similar via extending a common base class for all stream types.

An alternative design might be a factory or provider pattern as we could set values in the factory and provider and then only create the final stream object once the stream has been identified. The issue with this approach however is that it does two times the allocations in the worst case (even with pooling) as for each incoming stream we need to allocate a factory and a stream.

### Additional context

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.