-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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 caused by caching all unique paths seen #2084
Conversation
Generated by 🚫 danger |
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.
Yes ouch. Care to fix CHANGELOG please, I'll merge.
CHANGELOG.md
Outdated
@@ -6,6 +6,7 @@ | |||
* [#2060](https://github.com/ruby-grape/grape/pull/2060): Drop support for Ruby 2.4 - [@dblock](https://github.com/dblock). | |||
* [#2060](https://github.com/ruby-grape/grape/pull/2060): Upgraded Rubocop to 0.84.0 - [@dblock](https://github.com/dblock). | |||
* [#2077](https://github.com/ruby-grape/grape/pull/2077): Simplify logic for defining declared params - [@dnesteryuk](https://github.com/dnesteryuk). | |||
* [#2084](https://github.com/ruby-grape/grape/pull/2084): Fix memory leak in path normalization- [@fcheung](https://github.com/fcheung). |
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.
Missing space before -
Also cc: @ericproulx you'll want to take a look at this. |
This optimisation was introduced in ruby-grape#2002. If an api's paths include an id in the path then this cache can grow in an unbounded manner.
Thanks - I have fixed changelog. Running 1.3.3 + this patch on one of our hosts at the moment & memory usage seems stable enough. |
I don't mind reverting. I'll try to find a way to keep the most unique api calls instead of just adding all of them. Creating a kind of LRU policy but inside a ruby hash. |
Grape v1.4.0 fixes a memory leak that was present in v1.3.3 (ruby-grape/grape#2084). Full list of changes: * https://github.com/ruby-grape/grape/blob/master/CHANGELOG.md * https://github.com/ruby-grape/grape/compare/v1.3.3..v1.4.0
Besides upgraded Grape, it changes the response body for 204 HTTP status, now it is an empty string instead of an empty hash. Rack introduced lazy body initialization (rack/rack@8c62821) which only works with strings. However, when 204 HTTP status is returned, Grape doesn't stringify the response (https://github.com/ruby-grape/grape/blob/master/lib/grape/middleware/formatter.rb#L27-L29), thus, a hash is returned as a response body. `Rack::MockResponse` fails with TypeError (no implicit conversion of Hash into String) It could be a bug in the JsonAPI resources gem, why does it return an empty hash for 204 HTTP status?!. Definetly, it isn't a bug in Grape, nor Rack. The logic for formatting the reponse body in Grape hasn't changed for 5 years. The main motivation for this upgrade is a fix for memory leak ruby-grape/grape#2084
I recently updated one of our apps from grape 1.2.5 to 1.3.3 and have observed a memory leak. After analysing some heap dumps taken from our app I believe I have tracked this back to part of the changes in #2002
The change to router.rb caches normalized paths here: https://github.com/ruby-grape/grape/blob/master/lib/grape/router.rb#L10
This retains indefinitely every path that flows through grape. We have a number of apis where the path is of the form
foo/bar/id/action
where id is the id of the object the api call is acting on, so this grows in a more or less unbounded way.Since this was just a memory optimization, I would suggest just reverting that part of the changes in #2002 which is what this PR does