Replies: 2 comments 2 replies
-
@mnovelo This sounds great to me.
If methods need to be overridden, perhaps hooks can be added to Active Record to make this part of the API. Worth raising a Rails issue for it anyway.
If the tenant ever has a risk of leaking outside its scope then that can be a disastrous bug leading to huge security issues. I don't know how the Apartment gem works internally, but I'd love to see additional guard rails in place to prevent this from happening. Maybe check
Instead of solving |
Beta Was this translation helpful? Give feedback.
-
This is a great overview and I think a great direction for a solid v4 that would be an awesome update. Do you have any thoughts on versions of rails itself you would want or need to continue to support, to also help drive any API or dependency decisions? If you wanted to support for example only rails 7.0 and newer, or rails 6.0 or newer, that could drive some decisions perhaps. My other initial thought would be that indeed using ActiveSupport::CurrentAttributes would be the current rails way of thread specific state, and build upon some newer community standards. I don't imagine it would help solve #304 directly, perhaps indeed a new rails API to expose hooks would be helpful here to modify behavior upon spawn, but without that, the workaround listed in the issue by the author would be the best solution indeed, that we could build upon. |
Beta Was this translation helpful? Give feedback.
-
Hi everyone,
For v4, I’d like to focus on improving concurrency and thread/fiber safety in the Apartment gem. With Rails supporting multiple databases and async queries, there are increasing demands on how we manage tenants across threads, fibers, and connections. I believe v3 has significant limitations in this regard, particularly with connection pooling and multi-threaded contexts.
Current Challenges
1. Concurrency Issues Across Databases
Schema-based tenancy (PostgreSQL):
In PostgreSQL, we rely heavily on
SET search_path
to manage tenants. However, we lack a robust way to track or reset thesearch_path
per connection, causing issues with tools like RDS Proxy (#302). This also creates problems in tests where shared connections across threads lead to unpredictable tenant state (#239).Database-based tenancy (MySQL):
For MySQL, where each tenant is its own database, switching tenants frequently creates new connections, which hampers connection pooling efficiency. This is especially problematic in setups with read replicas (#275).
2. Async Query Support
Rails 7’s
load_async
queries fail to respect the tenant context when executed on async thread pools, resulting in queries falling back to thepublic
schema (#199).3. ActionController::Live
Threads spawned by
ActionController::Live
bypass tenant state, requiring manual intervention to maintain the tenant context (#304).4. Schema Dumping
The
schema.rb
dump currently excludescreate_schema
calls for non-tenant schemas, which is frustrating for apps with shared or analytics schemas (#303).Proposed Direction
1. Leverage
ActiveSupport::CurrentAttributes
CurrentAttributes
to track the “current tenant” uniformly across threads and fibers.2. Integrate with Rails Connection Pooling
Apartment
to work seamlessly with Rails’ connection pool by overriding key methods inActiveRecord::ConnectionHandling
andActiveRecord::Core
.search_path
per connection.3. Support Async Queries and ActionController::Live
load_async
andActionController::Live
.4. Configurable Schema Dumping
schema.rb
dumps.Feedback Requested
I’m open to thoughts on the following:
Let me know what you think or if you’d like to collaborate on specific areas!
Beta Was this translation helpful? Give feedback.
All reactions