Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
FreshConnection allows access to Mysql slave servers in Rails.
Ruby
Failed to load latest commit information.
gemfiles
lib
log
test
.gitignore
.travis.yml
Appraisals
Gemfile
LICENSE.txt
README.md
Rakefile
fresh_connection.gemspec

README.md

FreshConnection

FreshConnection allows access to Mysql slave servers in Rails.

Gem Version Build Status Code Climate

ActiveRecord can only access a single server by default.
FreshConnection can access to replicated Mysql slave servers via a loadbalancer.

For example.

Rails ------------ Mysql(Master)
             |
             |                     +------ Mysql(Slave1)
             |                     |
             +---- Loadbalancer ---+
                                   |
                                   +------ Mysql(Slave2)

When Rails controller's action begins, FreshConnction connects with one of slave servers behind the loadbalacer.
Read query goes to the slave server via the loadbalancer.
Write query goes to the master server. Inside transaction, all queries go to the master server.
All Mysql connections is disconnected at the end of the Rails controller's action.

Usage

Read query goes to the slave server.

Article.where(:id => 1)

If you want to access to the master server, use read_master.

Article.where(:id => 1).read_master

It is possible to use readonly(false) instead of read_master, but it is depricated.

In transaction, All queries go to the master server.

Article.transaction do
  Article.where(:id => 1)
end

Create, Update. Delete queries go to the master server.

article = Article.create(...)
article.title = "FreshConnection"
article.save
article.destory

Installation

Add this line to your application's Gemfile:

gem "fresh_connection"

And then execute:

$ bundle

Or install it yourself as:

$ gem install fresh_connection

Config

config/database.yml

production:
  adapter: mysql2
  encoding: utf8
  reconnect: true
  database: kaeru
  pool: 5
  username: master
  password: master
  host: localhost
  socket: /var/run/mysqld/mysqld.sock

  slave:
    username: slave
    password: slave
    host: slave

slave is a config to connect to slave servers. Others will use the master server setting.

use multiple slave servers group

If you may want to use multiple slave groups, write the config to config/database.yml.

production:
  adapter: mysql2
  encoding: utf8
  reconnect: true
  database: kaeru
  pool: 5
  username: master
  password: master
  host: localhost
  socket: /var/run/mysqld/mysqld.sock

  slave:
    username: slave
    password: slave
    host: slave

  admin_slave:
    username: slave
    password: slave
    host: admin_slaves

And call the establish_fresh_connection method in a model that access to admin_slave slave group.

class AdminUser < ActiveRecord::Base
  establish_fresh_connection :admin_slave
end

The model of children class will access to same slave group as the parent.

class Parent < ActiveRecord::Base
  establish_fresh_connection :admin_slave
end

class AdminUser < Parent
end

class Benefit < Parent
end

AdminUser and Benefit access to admin_slave slave group.

Declare model that doesn't use slave db

class SomethingModel < ActiveRecord::Base
  master_db_only!
end

If a model that always access to the master server is exist, You write master_db_only! in the model. The model that master_db_only model's child is always access to master db.

for Unicorn

before_fork do |server, worker|
  ...
  ActiveRecord::Base.clear_all_slave_connections!
  ...
end

after_fork do |server, worker|
  ...
  ActiveRecord::Base.establish_fresh_connection
  ...
end

Slave Connection Manager

Default slave connection manager is FreshConnection::ConnectionManager. If you would like to change slave connection manager, assign yourself slave connection manager.

config/initializers/fresh_connection.rb

FreshConnection.connection_manager = MySlaveConnection

Yourself Slave Connection Manager should be inherited FreshConnection::AbstractConnectionManager

class MySlaveConnection < FreshConnection::AbstractConnectionManager
  def slave_connection
    # must return object of ActiveRecord::ConnectionAdapters::Mysql2Adapter
  end

  def put_aside!
    # called when end of Rails controller action
  end

  def recovery(failure_connection, exception)
    # called when raise exception to access slave server
  end
end

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Test

I'm glad that you would do test! To run the test suite, you need mysql installed. How to setup your test environment.

First of all, you setting the config of the test mysql server in spec/database.yml

bundle install --path .bundle
bundle exec appraisal install

This command run the spec suite for all rails versions supported.

bundle exec appraisal rake test
Something went wrong with that request. Please try again.