Description
There is a memory leak related to remounting apis. It was originally addressed here.
I believe this is an incomplete solution. The root of the issue is calling the add_setup
method every time a class method is called on a Grape::API
subclass instead of on a Grape::API::Instance
subclass.
The way this is coded up, we are going have have to keep dealing with this issue one method at a time.
It also can happen with methods created outside of the grape gem if you follow the instructions in the upgrading guide, and unless you do some really hack ruby stuff to unfreeze the collection and add your methods, there is no way to get them included in the blacklist.
Here is a quick example of something that causes the leak.
App::API.instance_variable_get(:@setup).length
=> 27
1000.times do
App::API.versions
end;
App::API.instance_variable_get(:@setup).length
=> 1027
To inspect a full list of affected methods, just do this in your closest grape based app.
(App::API.base_instance.methods - Grape::API::NON_OVERRIDABLE).sort
A quick list of notable methods that stick out to me from that list are:
base, endpoints, logger, instance, versions...
Basically, any method that is not part of the DSL for building/describing a Grape::API::Instance
.
Because of this issue, his line from the upgrading guide is not factual.
This changes were done in such a way that no code-changes should be required.
I believe this needs to be address properly or that line needs to change to warn users about invoking methods on a Grape::API
class.
I'm not familiar enough with the code to make a real suggestion for fixing it, but I dont think this is a very sane way to "copy"
an object. Also, in the switch from being class based to "class instance"
(subclasses) based, I think someone forgot about actual instances.
The DSL's build up state that should be clonable when creating the "class instances"
. Alternatively, instead of a blacklist of methods, potentially there could be a whitelist of methods that are part of the DSL for describing a Grape::API::Instance
.