Skip to content
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

Use Inheritance instead of Composition to Reduce allocation in Request Decompression Middleware #42324

Open
Kahbazi opened this issue Jun 21, 2022 · 3 comments
Labels
area-middleware Includes: URL rewrite, redirect, response cache/compression, session, and other general middlesware area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions investigate Perf
Milestone

Comments

@Kahbazi
Copy link
Member

Kahbazi commented Jun 21, 2022

I've opened this issue to discuss the idea that I've mentioned in here and here now that Request Decompression Middleware is merged.

At the moment IDecompressionProvider is creating a decompression stream and the middleware creates a SizeLimitedStream which wraps the other one. We could reduce this two streams into one if the IDecompressionProvider returns a stream that also handle size limit check, and the middleware only create SizeLimitedStream if the returned stream from the IDecompressionProvider is not marked with IDontNeedWrapper interface.

+internal interface IDontNeedWrapper {}
+internal sealed class GZipRequestDecompressionBody : GZipStream, IDontNeedWrapper {}
+internal sealed class DeflateRequestDecompressionBody : DeflateStream , IDontNeedWrapper {}
+internal sealed class BrotliRequestDecompressionBody : BrotliStream, IDontNeedWrapper {}

The new types for this change are all private, so there's no new public types. By doing this we would reduce one allocation per requests when request body is compressed by GZip, Deflate or Brotli.

@adityamandaleeka
Copy link
Member

Triage: we'd need to see perf numbers to decide whether the impact of this is worth the complexity. A small improvement in this decompression scenario may not be worth it...

@ghost
Copy link

ghost commented Jun 22, 2022

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

@david-acker
Copy link
Member

I made these changes locally and there only seems to be an allocation-related improvement for compressed requests when IRequestSizeLimitMetadata exists (reduced from 3 KB to 2 KB). Apart from that, it doesn't look like much else changed, although I'm not too familiar with interpreting these benchmarks.

Benchmark Results

I also noticed a few complications when implementing and testing this:

  1. The BrotliStream class is sealed, so we'll only be able to create new types for Deflate and GZip.
  2. The CopyTo and CopyToAsync methods on the GZipStream pass their operations to a DeflateStream that's used internally which circumvented the size limit check I added and caused some test failures. I not sure if this was to be expected, but it doesn't seem like adding the size limit check will be as straight forward as overriding the Read and ReadAsync methods like it was for the original SizeLimitedStream.

@amcasey amcasey added area-middleware Includes: URL rewrite, redirect, response cache/compression, session, and other general middlesware area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions and removed area-runtime labels Aug 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-middleware Includes: URL rewrite, redirect, response cache/compression, session, and other general middlesware area-networking Includes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions investigate Perf
Projects
None yet
Development

No branches or pull requests

5 participants