Using RequestStore with Sidekiq
masterRequestStore does not clear the store during background job processing. To ensure the store is cleared after each Sidekiq job for security and consistency, use the companion library request_store-sidekiq.repository·master·Indexed 23 days ago
https://github.com/steveklabnik/request_storeA thread-safe, request-local storage mechanism for Ruby applications designed to prevent data leaking between requests in multi-threaded web servers like Puma or Thin. It provides a hash-like interface via RequestStore.store and a fetch method for cached values. The library includes RequestStore::Middleware for Rack and Rails integration to ensure storage is automatically cleared after requests, including support for streaming responses and Rails reloader integration.
RequestStore does not clear the store during background job processing. To ensure the store is cleared after each Sidekiq job for security and consistency, use the companion library request_store-sidekiq.Add request_store to your application's Gemfile to provide request-local storage that avoids the concurrency bugs associated with using Thread.current in threaded web servers like Puma or Thin.
gem 'request_store'If you are not using Rails, you must manually include the RequestStore::Middleware in your Rack stack to ensure the store is cleared after each request.
use RequestStore::MiddlewareWhile Rails 3+ applications are automatically configured via a Railtie, Rails 2.x applications require manual middleware configuration. Add the following to your config/environment.rb:
config.middleware.use RequestStore::MiddlewareWhen used within a Rails application, RequestStore automatically configures itself via a Railtie. It inserts RequestStore::Middleware into the middleware stack to ensure the request-local storage is initialized and cleared correctly.
Specifically, it handles middleware placement based on the presence of ActionDispatch::RequestId (inserting after it) or falls back to inserting after Rack::MethodOverride. It also integrates with the Rails reloader (ActiveSupport::Reloader or ActionDispatch::Reloader) to call RequestStore.clear! during the reloading process, preventing data leakage between requests in development environments.
When using Rack::Test for testing, ensure the RequestStore::Middleware is included in your app definition so that storage is cleared between test requests.
# spec_helper.rb
def app
Rack::Builder.new do
use RequestStore::Middleware
run MyApp
end
endReplace usage of Thread.current with RequestStore.store to ensure that data is local to the current request and is automatically cleared after the request completes. This prevents data from leaking between requests in threaded environments.
def index
RequestStore.store[:foo] ||= 0
RequestStore.store[:foo] += 1
render :text => RequestStore.store[:foo]
endThe fetch method returns the stored value if it already exists. If no stored value exists, it executes the provided block, stores the result in the RequestStore, and returns it.
top_posts = RequestStore.fetch(:top_posts) do
# code to obtain the top posts
end~>) in your gemspec to ensure compatibility within a major version.The RequestStore module implements several methods that mirror the standard Ruby Hash API for interacting with the underlying storage:
RequestStore.store: Returns the underlying hash object.RequestStore.store=(store): Replaces the entire store with a new hash.RequestStore.[](key) / RequestStore[]= (key, value): Standard bracket access for reading and writing.RequestStore.delete(key, &block): Removes a key from the store, optionally using a block to return a value.RequestStore::Middleware ensures that the RequestStore remains available until the last part of the response body is rendered. This is specifically useful when using streaming responses, as it prevents the store from being cleared prematurely before the stream is fully consumed. It utilizes Rack::BodyProxy to trigger RequestStore.end! and RequestStore.clear! once the body has been processed.RequestStore module provides a way to store data that is local to the current thread (typically a single web request). It uses Thread.current to ensure data isolation between different requests in a multi-threaded environment. You can use it to store and retrieve values using a hash-like interface.