Short Version
Are class variables thread-safe for the duration of a controller action?
Long Version
I'm writing a Rails 3 app that implements multi-tenancy using a single database schema with tenant_id
columns in each table to identify to whom the data belongs.
Naturally I need a way to scope all queries that are run on the database to ensure that access to data is properly isolated per-tenant.
Several people have suggested achieving this by always accessing the database through the tenant
instance, e.g.:
current_tenant.associate_collection.where(...)
etc.
However, since multi-tenancy is an architectural concern (not a business domain concern), I'd prefer to keep this as transparent to the model as possible by setting it up the scope globally. It's also much DRYer.
I've found I can do this using the multitenant gem and around_filters:
class ApplicationController
around_filter do
Multitenant.with_tenant current_tenant
yield
end
end
end
This manipulates the default_scope
of the appropriate models so that all data access is automatically scoped to the current tenant.
This works great in development, but I have concerns about thread safety. Multitenant.with_tenant
preserves the current_tenant
reference in a class variable.
The question is can I rely on the integrity of that variable while the controller action is on the stack? or could it be corrupted by another request?
Also, what’s a good source on general concurrency issues in Rails?