Module: ReadFromSlave
- Defined in:
- lib/read_from_slave.rb,
lib/read_from_slave/railtie.rb
Overview
Read_from_slave for Rails enables database reads from one or more slave databases, while writes continue to go to the master To use read_from_slave you must install the gem, configure the gem in your environment file, and setup your database.yml file with an entry for your slave database.
gem install read_from_slave
Read_from_slave is compatible with Rails 2.2.x and Rails 3
Configuration
In config/environments/production.rb (for instance)
config.gem "read_from_slave"
In config/database.yml
production:
adapter: mysql
database: mydatabase
username: myuser
password: mypassword
host: my.main.database.server.com
port: 3306
slaves:
slave_1: slave_for_reads
slave_2: slave_for_reporting
slave_for_reads:
adapter: mysql
database: mydatabase
username: myuser
password: mypassword
socket: /var/lib/mysql/mysql.sock
slave_for_reporting:
adapter: mysql
database: mydatabase
username: myuser
password: mypassword
host: my.slave.database.server.com
Note that if you have multiple databases you can also configure multiple slaves.
References
-
“Masochism”:github.com/technoweenie/masochism/tree/master
** not thread safe ** won’t work with apps that talk to multiple (master) databases
-
“Acts as readonlyable”:rubyforge.org/projects/acts-as-with-ro/
** old, not suitable for Rails 2.x
-
“master_slave_adapter”:github.com/mauricio/master_slave_adapter/tree/master
** similar to read_from_slave, but adapter based approach
-
“multi_db”:github.com/schoefmax/multi_db/tree/master
** another one, proxy connection approach ** looks like it won’t work with apps that talk to multiple (master) databases ** more complex than read_from_slave
Defined Under Namespace
Modules: CalculationMethod, ClassMethods, InstanceMethods Classes: Railtie
Constant Summary collapse
- @@all_reads_on_slave =
true
Class Method Summary collapse
- .all_reads_on_slave ⇒ Object
- .all_reads_on_slave=(all_reads) ⇒ Object
- .default_to_master! ⇒ Object
- .install! ⇒ Object
- .install_with_methods! ⇒ Object
Class Method Details
.all_reads_on_slave ⇒ Object
114 115 116 |
# File 'lib/read_from_slave.rb', line 114 def all_reads_on_slave @@all_reads_on_slave end |
.all_reads_on_slave=(all_reads) ⇒ Object
109 110 111 112 |
# File 'lib/read_from_slave.rb', line 109 def all_reads_on_slave=(all_reads) @@all_reads_on_slave = all_reads default_to_master! end |
.default_to_master! ⇒ Object
99 100 101 102 103 104 105 106 |
# File 'lib/read_from_slave.rb', line 99 def default_to_master! base = ActiveRecord::Base base.class_eval do class << self alias_method_chain :connection, :slave_db_scope unless ReadFromSlave.all_reads_on_slave end end end |
.install! ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/read_from_slave.rb', line 59 def install! base = ActiveRecord::Base base.send(:include, InstanceMethods) base.alias_method_chain :reload, :read_from_slave base.extend(ClassMethods) base.class_eval do class << self alias_method_chain :find_by_sql, :read_from_slave alias_method_chain :connection, :read_from_slave end end begin calculation_base = ActiveRecord::Relation # rails 3 calculation_base.send(:include, CalculationMethod) calculation_base.alias_method_chain :calculate, :read_from_slave rescue NameError # rails 2 base.extend(CalculationMethod) base.class_eval do class << self alias_method_chain :calculate, :read_from_slave end end end end |
.install_with_methods! ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/read_from_slave.rb', line 85 def install_with_methods! ActiveRecord::Base.connection.instance_variable_get(:@config)[:slaves].each_key do |slave_name| ActiveRecord::Base.class_eval <<-EOM def self.with_#{slave_name}(&block) Thread.current[:with_#{slave_name}_count] ||= 0 Thread.current[:with_#{slave_name}_count] += 1 yield ensure Thread.current[:with_#{slave_name}_count] -= 1 end EOM end if ActiveRecord::Base.connection.instance_variable_get(:@config)[:slaves] end |