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

Adding sync.Pool to Decompress middleware #1699

Merged
merged 2 commits into from
Dec 11, 2020

Conversation

pafuent
Copy link
Contributor

@pafuent pafuent commented Nov 27, 2020

Fixing a http.Request.Body leak on the decompress middleware that were not properly Close
Removing the defer on the call to gzip.Reader, because that reader is already exhausted after the call to io.Copy

Fixing a http.Request.Body leak on the decompress middleware that were
not properly Close
Removing the defer on the call to gzip.Reader, because that reader is
already exausted after the call to io.Copy
@pafuent pafuent self-assigned this Nov 27, 2020
@codecov
Copy link

codecov bot commented Nov 27, 2020

Codecov Report

Merging #1699 (2386e17) into master (502cce2) will decrease coverage by 0.01%.
The diff coverage is 86.20%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1699      +/-   ##
==========================================
- Coverage   84.88%   84.86%   -0.02%     
==========================================
  Files          29       29              
  Lines        1945     1969      +24     
==========================================
+ Hits         1651     1671      +20     
- Misses        187      189       +2     
- Partials      107      109       +2     
Impacted Files Coverage Δ
middleware/decompress.go 88.37% <85.71%> (-6.37%) ⬇️
middleware/compress.go 84.31% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 502cce2...2386e17. Read the comment docs.

@pafuent
Copy link
Contributor Author

pafuent commented Nov 27, 2020

@arun0009 Could you please review this PR?
Sadly I didn't had the time to review the PR in which you added the Decompress middleware, and I saw it when it was merged.
Besides the use of a sync.Pool (which I bring from the Compress middleware), I think that the gzip.Reader could be Close without the defer and that the http.request.Body that is replaced at the end, should be closed. When the Body is not changed, is the Server the one responsible for closing it.

@pafuent
Copy link
Contributor Author

pafuent commented Nov 27, 2020

Codecov is failing because I'm no testing some error code branches, that sadly I don't know how to test. If someone have any suggestion, I'll be glad to implement it.

Here are the benchmarks comparison for this change. In this case I did 10 iterations instead of the 5 performed on our GitHub action

name          old time/op    new time/op    delta
Decompress-2    2.21µs ± 6%    2.08µs ± 6%   -6.01%  (p=0.003 n=10+10)

name          old alloc/op   new alloc/op   delta
Decompress-2    5.49kB ± 0%    4.91kB ± 0%  -10.60%  (p=0.000 n=10+9)

name          old allocs/op  new allocs/op  delta
Decompress-2      12.0 ± 0%      11.0 ± 0%   -8.33%  (p=0.000 n=10+10)

gr.Close()
pool.Put(gr)

b.Close() // http.Request.Body is closed by the Server, but because we are replacing it, it must be closed here
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch!

@arun0009
Copy link
Contributor

Codecov is failing because I'm no testing some error code branches, that sadly I don't know how to test. If someone have any suggestion, I'll be glad to implement it.

Here are the benchmarks comparison for this change. In this case I did 10 iterations instead of the 5 performed on our GitHub action

name          old time/op    new time/op    delta
Decompress-2    2.21µs ± 6%    2.08µs ± 6%   -6.01%  (p=0.003 n=10+10)

name          old alloc/op   new alloc/op   delta
Decompress-2    5.49kB ± 0%    4.91kB ± 0%  -10.60%  (p=0.000 n=10+9)

name          old allocs/op  new allocs/op  delta
Decompress-2      12.0 ± 0%      11.0 ± 0%   -8.33%  (p=0.000 n=10+10)

One way of testing InternalServerError or pool error handling is by using interfaces. Here's an example that would cover 91.9% of code base https://gist.github.com/arun0009/f8a19659cf956b82e3abadc2211e3be0

@pafuent
Copy link
Contributor Author

pafuent commented Nov 28, 2020

Thanks for the advice @arun0009

var buf bytes.Buffer
io.Copy(&buf, gr)

gr.Close()
pool.Put(gr)
Copy link
Contributor

@arun0009 arun0009 Dec 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pafuent - you are putting gr back to pool twice? On line 100 and 110? Also, whats resetting gr before putting it back in pool? of is it the usage of gr.Reset making sure that it's reset before reading new request body?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 100 because the call to Reset returned an error, so the middleware is skipped (for empty bodies) or returns the error (all the rest of the errors). And the line 110 is the happy path 😉
I'm not using a defer just to return it to the Pool as fast as is possible to avoid an allocation if a new request find the Pool empty.
Reset() requires the io.Reader, so I need to perform that after getting one instance from the Pool

@lammel
Copy link
Contributor

lammel commented Dec 7, 2020

Looks like you also added the missing test for the error path.
Are we ready to merge @pafuent ?

@pafuent
Copy link
Contributor Author

pafuent commented Dec 11, 2020

@lammel, yes it's ready to be merged

@lammel lammel merged commit 194129d into labstack:master Dec 11, 2020
@pafuent pafuent deleted the improve_decompress_middleware branch December 14, 2020 03:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants