Allow configuring HttpContext Pipe options
- 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.
I'm attempting to optimize streaming response bodies from Postgres through asp.net via Npgsql's large object manager. While going down a rabbit hole creating incremental hash pipe wrappers, I noticed that only `4096b` of memory is ever requested from the response body wrapper's `GetMemory` method.
After much digging around it appears that the commonly used `CopyToAsync(PipeWriter..)` convenience methods do not pass a `sizeHint` through, nor do any of the other buffer or size options factor into how much memory is requested. Both the extension on stream and the method on `StreamPipeReader` seems to end up calling bare `GetMemory` here: https://github.com/dotnet/runtime/blob/v7.0.3/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/PipeWriter.cs#L127 . This goes back to `Pipe` and seems to fall back on the `MinimumSegmentSize` which default to 4096.
### Describe the solution you'd like
If we could supply options to the Pipe constructor in the `HttpContextBuilder` we could establish a global minimum segment size.
A better solution IMHO(though in runtime) would be to properly wire `sizeHint` through all the `Pipe` APIs so this can be handled on a per-use basis. I can't tell if it wasn't fully introduced, or if it was but was ripped out 🤔
### Additional context
I'm seeing a pretty significant decrease in latency locally serving a 110k png to the browser. Latency drops from ~`10-14ms` to a ~`7-11ms` when I override `sizeHint` in my wrappers `GetMemory` method to `8192`. Doubling it again seems to drop down to a `5ms` best case with further reduction in variance.
Not super scientific and I was just introduced to `System.IO.Pipelines` yesterday so I'm not sure if I'm missing something obvious here..
Edit: I had previously linked to where the test host builder instantiates the pipe 😄 Have not yet been able to track down where Kestrel instantiates the `IDuplexPipe`(?) that underpins the response body writer..
Contributor guide
Assessment
This issue has not been assessed yet.