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

Fix memory leak on persistent connections #176

Merged
merged 3 commits into from
Jul 25, 2024

Conversation

willcosgrove
Copy link
Contributor

I noticed a memory leak in my Rails app. The app uses the searchkick gem for searching using elasticsearch. That in turn uses the faraday gem. I had opted to use httpx via it's faraday adapter so I could take advantage of a persistent connection to the elasticsearch server.

But recently I started noticing a memory leak in my application. After doing some investigative work on some heap dumps, I started to zero in on httpx, http-2-next, and now after a recent update, http-2.

It is at this point that I should stress: I have no idea what I'm doing. I've made a change here. It makes sense to me, as someone who knows literally nothing about what is required to build or design a working http/2 client. But it seemed like it could be the source of my leak, so I decided to patch it and run it in production on a Friday. 🎉

I'm now about 4 hours in to my inadvisable experiment, and astonishingly nothing seems to have broken. And the memory profile is now flat again!

I have no notion that this PR is worth merging in as is. But I wanted to open it just to say, that I'm fairly confident that there exists a memory leak in the HTTP2::Connection class as it is right now. And I'm reasonably confident that this change (however incorrect it is in other ways) seems to fix it, and not immediately cause other problems.

Thanks for your work on this gem. I hope this PR helps in some way, even if it isn't by providing mergable code.

@HoneyryderChuck
Copy link
Collaborator

Hi @willcosgrove ,

Thx for the patch. Indeed, it was a regression from this commit. Until then, stream was being removed only after the grace period. Still, I think your patch has legs, as the code already seems to handle frame selection on recently closed frames, while erroring on the rest. I'll do a bit more consideration til next week.

as per spec. fixed other tests wrongly using closed streams.
should account with last processed stream; also, avoid creation of expensive stream object in cases where condition is violated
@HoneyryderChuck
Copy link
Collaborator

fixed the failing tests, which were exposing incorrect behaviour of leaving streams hanging around in @streams. Managed to find an issue with stream order verification, as well as dealing with RST_STREAM on already closed streams.

@igrigorik @alextwoods can I ask you for a review on the changes here, given that some of them are mine? This seems an improvement on the state of stream close lifecycle management found on 0.12 (which only removed them on recently closed streams cleanup).

Copy link
Collaborator

@mullermp mullermp left a comment

Choose a reason for hiding this comment

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

LGTM

@willcosgrove
Copy link
Contributor Author

Just chiming in here to say that I updated our production deployment to 8f072b0 and it continues to run smoothly with no more memory leak

@HoneyryderChuck HoneyryderChuck merged commit 8511863 into igrigorik:main Jul 25, 2024
7 of 8 checks passed
@HoneyryderChuck
Copy link
Collaborator

v1.0.1 released.

@willcosgrove willcosgrove deleted the remove-closed-streams branch July 29, 2024 14:46
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