ruby-grape / ruby-grape/grape

Memory Leak since 1.2.0

Open
#2,071 19 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

confirmed bug
Dominant language
Ruby
Stars
10k
Forks
1.2k
Avg merge
14h 38m
Merged PRs (30d)
92

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.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with add_setup in lib/grape/api.rb and the remounting changes linked from the issue. Reproduce the growth using App::API.instance_variable_get(:@setup) and repeated App::API.versions, then inspect the upgrading guidance in UPGRADING.md. Done means repeated class-method calls no longer grow setup state and the documented upgrade behavior is accurate.

Written by the indexing model from the issue text.

Assessment

Tech stack
ruby
Domain
api, backend
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.