Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Store thread-safe global request specific data with Rails

A lot of the Rails app I work on depends on a few request specific parameters (request_api_version, client_ip, device_id, ...).

For now these parameters are passed along in each method calls. That's pretty heavy. Is there a thread-safe smart way to store this data somewhere to avoid passing them?

I though about global variables such as MyApp.request_api_version but I don't see this is as good practice (not thread-safe, ...).

Any other options?

like image 487
Emmanuel Turlay Avatar asked Sep 04 '25 16:09

Emmanuel Turlay


1 Answers

tl;dr Use request_store.

Long version: threads in Ruby behave sort of like hashes (they respond to [] and []=), and you can access the current thread through Thread.current. This lets you do stuff like Thread.current[:client_ip] = request.ip in the controller, then client_ip = Thread.current[:client_ip] in your model. This works great until the app server reuses a thread to handle a second request. Then chaos ensues and the universe is destroyed (or something).

The request_store gem handles this by wrapping every request in a special middleware that "cleans up" anything you store after the HTTP response has been sent. It's pretty trivial to implement this yourself, especially if you're only using a couple variables. If you want a more generally useful solution though, just use the gem.

like image 81
James Mason Avatar answered Sep 07 '25 07:09

James Mason