Ever needed to use a global variable in Rails? Ugh, that's the worst. If you need global state, you've probably reached for
Thread.current
.
When you're using Thread.current
, you must make sure you're cleaning up after yourself. Else, values stored in one request may be available to the next (depending on your server). request_store wipes all data when a request ends and makes per-request global storage a no-brainer. Internally, it's using Thread.current
with a Hash
in a simple middleware.
Example: Remembering all currently available tags in the system.
class Tag
def self.all_cached
RequestStore[:tags] ||= all
end
end
The underlying data structure is a Hash, so you can use methods like exist?
, fetch
or delete
if you need to.
Using RequestStore outside of web worker requests
Note that RequestStore
just uses Thread.current
under the hood and injects a Rack middleware that calls RequestStore.clear!
after each request.
If you use RequestStore
in a non-request context where (like background jobs), you must clear the store yourself or your cached data will stay in Thread.current
. For Sidekiq, you can use
request_store-sidekiq
Show archive.org snapshot
.
Cronjobs are unaffected, as a new process is created each time.