SwitchPoint
Switching database connection between readonly one and writable one.
Installation
Add this line to your application's Gemfile:
gem 'switch_point'
And then execute:
$ bundle
Or install it yourself as:
$ gem install switch_point
Usage
See spec/models.
auto_writable
auto_writable
is disabled by default.
When auto_writable
is enabled, destructive queries is sent to writable connection even in readonly mode.
But it does NOT work well on transactions.
Suppose after_save
callback is set to User model. When User.create
is called, it proceeds as follows.
- BEGIN TRANSACTION is sent to READONLY connection.
- switch_point switches the connection to WRITABLE.
- INSERT statement is sent to WRITABLE connection.
- switch_point reset the connection to READONLY.
- after_save callback is called.
- At this point, the connection is READONLY and in a transaction.
- COMMIT TRANSACTION is sent to READONLY connection.
connection-related methods of model
Model has several connection-related methods: connection_handler
, connection_pool
, connected?
and so on.
Since only connection
method is monkey-patched, other connection-related methods doesn't work properly.
If you'd like to use those methods, send it to Model.switch_point_proxy.model_for_connection
.
Internals
There's a proxy which holds two connections: readonly one and writable one. A proxy has a thread-local state indicating the current mode: readonly or writable.
Each ActiveRecord model refers to a proxy.
ActiveRecord::Base.connection
is hooked and delegated to the referred proxy.
When the writable connection is requested to execute destructive query, the readonly connection clears its query cache.
Special case: ActiveRecord::Base.connection
Basically, each connection managed by a proxy isn't shared between proxies. But there's one exception: ActiveRecord::Base.
If :writable
key is omitted (e.g., Nanika1 model in spec/models), it uses ActiveRecord::Base.connection
as writable one.
When ActiveRecord::Base.connection
is requested to execute destructive query, all readonly connections managed by a proxy which uses ActiveRecord::Base.connection
as a writable connection clear query cache.
Contributing
- Fork it ( https://github.com/eagletmt/switch_point/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request