Store global objects into thread-local variables #711
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Context
Bullet stores global objects into fiber-local variables before each request, uses these global objects to collect all N+1 queries and later shows all collected problems based on these global objects result. This approach works well until someone don't try to run his code inside Fiber like this
In that case bullet warning is not shown because all global objects are stored as fiber-local variables for current Fiber and not passed to all new Fibers
Decision
The easiest way is to store bullet objects into thread-local variables instead: https://ruby-doc.org/core-2.6/Thread.html#class-Thread-label-Fiber-local+vs.+Thread-local
Changes
Notes
this problem can easily occur even when rails app does not use fibers explicitly but instead uses some 3rd party libraries like dry-rb/dry-effects#82