Read more

request_store: Per-request global storage for your Rails app

Dominik Schöler
July 06, 2016Software engineer at makandra GmbH

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.

Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show archive.org snapshot

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.

Posted by Dominik Schöler to makandra dev (2016-07-06 15:12)