I use the request_store gem, it works great.
My use case is for adding methods to the user model class, like the current_user, their locale, location etc as often my other models need this information.
I just setup the current user from my application controller:
User.current = the_authenticated_user
User.request = request
And in my user model class:
class User
def self.current
RequestStore.store[:current_user]
end
def self.current=(user)
RequestStore.store[:current_user] = user
end
def self.request
RequestStore.store[:current_request]
end
def self.request=(request)
# stash the request so things like IP address and GEO-IP based location is available to other models
RequestStore.store[:current_request] = request
end
def self.location
# resolve the location just once per request
RequestStore.store[:current_location] ||= self.request.try(:location)
end
end
I don't enable the reload classes option as it causes too many problems, I've witnessed multiple versions of classes hanging around. If you use model inheritance (ie STI) lazy loading and/or dynamic class loading will often break how model classes are resolved. You need to use require_dependency in your base and intermediate model classes to ensure downstream classes also get loaded.
My development settings mirror my production settings wrt class handling which is not convenient (requires server restart after a change) but more convenient than chasing non-existent bugs. The rerun gem can monitor file-system changes and restart your server for you so that you get reliable change handling in development, albeit slower than rails broken class reloading.
config/environment/development.rb:
# Rails class reloading is broken, anytime a class references another you get multiple
# class instances for the same named class and that breaks everything. This is especially
# important in Sequel as models resolve classes once.
# So always cache classes (true)
config.cache_classes = true
# Always eager load so that all model classes are known and STI works
config.eager_load = true
Q: How threadsafe classes variables?
A: No variables are thread safe unless protected by synchronize
.
From an architectural perspective threading in Rails is a waste of time. The only way I have been able to get true parallel performance/concurrency is multiple processes. It also avoids locking and threading related overheads that just don't exist with long running processes. I tested parallel CPU intensive code using threads with Ruby 2.x and got no parallelism at all. With 1 ruby process per core I got real parallelism.
I would seriously consider Thin with multiple processes and then decide if you want to use Thin+EventMachine to increase overall throughput per process.