request_store: Per-request global storage for your Rails app

Updated . Posted . Visible to the public.

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.

Dominik Schöler
Last edit
Arne Hartherz
License
Source code in this card is licensed under the MIT License.
Posted by Dominik Schöler to makandra dev (2016-07-06 13:12)