-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Avoid possible memory leak in compress middleware #919
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
Conversation
VojtechVitek
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Thanks for the detailed report and additional test cases. Really nice work!
|
@VojtechVitek @pkieltyka Thanks for the review and merging the PR 🙏 Do we have a rough estimation of when the new release containing these changes will be created? We would love to pull the fix as soon as possible. Thinking now if we should point to the commit hash from the |
|
@Neurostep can you |
|
@VojtechVitek That makes sense 👍 We will check changes from the |
|
@VojtechVitek Just following up here. We have deployed the Thanks again for the reviews and quick turnaround 🙏 |
|
Hi @Neurostep, this is great! Thanks you for reporting back! I'll release v5.0.13 shortly. 🎉 |
|
I think something might be wrong with f10dc4a Using the compression middleware, i get 'extra bytes' at the end of the document: This does not happen if i rebuild the binary with 5.0.12 (or drop the compression middleware) |
Description
In one of the HTTP services I am working on, we use the
compressmiddleware provided bychi. We use standardgzip, deflatecompression alongside withbrotlicompression.The important aspect of the HTTP endpoint that uses the
compressionmiddleware is that the content may or may not be of a compressible type, servingjsonandHTMLalongsidepngandjpg.For the
brotlicompression we use the official CGO wrapper. The following code snippet is used to set the encoder:After enabling the
brotlicompression in the production environment, we noticed a memory leak in the service although there was no any issues withgzipcompression.After the investigation, we noticed no memory leak indicated by the Go runtime profiles. After this we started looking into the
brotlilibrary implementation.Instrumented with the bcc tools (BPF Compiler Collection) we were able to find the leak:
It is clear from the report we are leaking the memory instantiated by the brotli writer. Looking at the source code of the compress middleware, we should call the underlying Close of the CGO writer which in turn should free up the C-allocated memory. We checked if the BrotliEncoderDestroyInstance is being called using the
funccount-bpfcc:Turned out, the
BrotliEncoderDestroyInstancefunction is not being called at the same rate asBrotliEncoderCreateInstancewhich explains the leak.After carefully looking into the go-chi middleware I realized we are calling the Close function returned by the writer() function, and writer() function returns instantiated writer only if the content is compressible.
In this PR we are trying to close the underlying
Writerif it satisfies theWriteCloserinterface, no matter if the content being served is compressible or not.Related links