Module: ActiveRecordSlave
- Defined in:
- lib/active_record_slave/active_record_slave.rb,
lib/active_record_slave/slave.rb,
lib/active_record_slave/errors.rb,
lib/active_record_slave/railtie.rb,
lib/active_record_slave/version.rb,
lib/active_record_slave/extensions.rb
Overview
ActiveRecord read from a slave
Defined Under Namespace
Modules: Extensions Classes: Railtie, Slave, TransactionAttempted
Constant Summary collapse
- VERSION =
'1.6.0'
- SELECT_METHODS =
Select Methods
[:select, :select_all, :select_one, :select_rows, :select_value, :select_values]
Class Method Summary collapse
-
.block_transactions ⇒ Object
When only reading from a slave it is important to prevent entering any into a transaction since the transaction still sends traffic to the master that will cause the master database to slow down processing empty transactions.
-
.block_transactions? ⇒ Boolean
Whether any attempt to start a transaction should result in an exception.
-
.ignore_transactions=(ignore_transactions) ⇒ Object
Set whether slave reads should ignore transactions.
-
.ignore_transactions? ⇒ Boolean
Returns whether slave reads are ignoring transactions.
-
.install!(adapter_class = nil, environment = nil) ⇒ Object
Install ActiveRecord::Slave into ActiveRecord to redirect reads to the slave Parameters: adapter_class: By default, only the default Database adapter (ActiveRecord::Base.connection.class) is extended with slave read capabilities.
-
.read_from_master ⇒ Object
Force reads for the supplied block to read from the master database Only applies to calls made within the current thread.
-
.read_from_master! ⇒ Object
Force all subsequent reads on this thread and any fibers called by this thread to go the master.
-
.read_from_master? ⇒ Boolean
Whether this thread is currently forcing all reads to go against the master database.
-
.read_from_slave ⇒ Object
The default behavior can also set to read/write operations against master Create an initializer file config/initializer/active_record_slave.rb and set ActiveRecordSlave.read_from_master! to force read from master.
-
.read_from_slave! ⇒ Object
Subsequent reads on this thread and any fibers called by this thread can go to a slave.
-
.read_from_slave? ⇒ Boolean
Whether this thread is currently forcing all reads to go against the slave database.
-
.skip_transactions ⇒ Object
During this block any attempts to start or end transactions will be ignored.
-
.skip_transactions? ⇒ Boolean
Whether any attempt to start a transaction should be skipped.
Class Method Details
.block_transactions ⇒ Object
When only reading from a slave it is important to prevent entering any into a transaction since the transaction still sends traffic to the master that will cause the master database to slow down processing empty transactions.
73 74 75 76 77 78 79 80 81 |
# File 'lib/active_record_slave/active_record_slave.rb', line 73 def self.block_transactions begin previous = Thread.current.thread_variable_get(:active_record_slave_transaction) Thread.current.thread_variable_set(:active_record_slave_transaction, :block) yield ensure Thread.current.thread_variable_set(:active_record_slave_transaction, previous) end end |
.block_transactions? ⇒ Boolean
Whether any attempt to start a transaction should result in an exception
117 118 119 |
# File 'lib/active_record_slave/active_record_slave.rb', line 117 def self.block_transactions? Thread.current.thread_variable_get(:active_record_slave_transaction) == :block end |
.ignore_transactions=(ignore_transactions) ⇒ Object
Set whether slave reads should ignore transactions
132 133 134 |
# File 'lib/active_record_slave/active_record_slave.rb', line 132 def self.ignore_transactions=(ignore_transactions) @ignore_transactions = ignore_transactions end |
.ignore_transactions? ⇒ Boolean
Returns whether slave reads are ignoring transactions
127 128 129 |
# File 'lib/active_record_slave/active_record_slave.rb', line 127 def self.ignore_transactions? @ignore_transactions end |
.install!(adapter_class = nil, environment = nil) ⇒ Object
Install ActiveRecord::Slave into ActiveRecord to redirect reads to the slave Parameters:
adapter_class:
By default, only the default Database adapter (ActiveRecord::Base.connection.class)
is extended with slave read capabilities
environment:
In a non-Rails environment, supply the environment such as
'development', 'production'
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/active_record_slave/active_record_slave.rb', line 21 def self.install!(adapter_class = nil, environment = nil) slave_config = if ActiveRecord::Base.connection.respond_to?(:config) ActiveRecord::Base.connection.config[:slave] else ActiveRecord::Base.configurations[environment || Rails.env]['slave'] end if slave_config ActiveRecord::Base.logger.info "ActiveRecordSlave.install! v#{ActiveRecordSlave::VERSION} Establishing connection to slave database" Slave.establish_connection(slave_config) # Inject a new #select method into the ActiveRecord Database adapter base = adapter_class || ActiveRecord::Base.connection.class base.include(Extensions) else ActiveRecord::Base.logger.info "ActiveRecordSlave not installed since no slave database defined" end end |
.read_from_master ⇒ Object
Force reads for the supplied block to read from the master database Only applies to calls made within the current thread
42 43 44 45 46 47 48 49 50 51 |
# File 'lib/active_record_slave/active_record_slave.rb', line 42 def self.read_from_master return yield if read_from_master? begin previous = Thread.current.thread_variable_get(:active_record_slave) read_from_master! yield ensure Thread.current.thread_variable_set(:active_record_slave, previous) end end |
.read_from_master! ⇒ Object
Force all subsequent reads on this thread and any fibers called by this thread to go the master
107 108 109 |
# File 'lib/active_record_slave/active_record_slave.rb', line 107 def self.read_from_master! Thread.current.thread_variable_set(:active_record_slave, :master) end |
.read_from_master? ⇒ Boolean
Whether this thread is currently forcing all reads to go against the master database
97 98 99 |
# File 'lib/active_record_slave/active_record_slave.rb', line 97 def self.read_from_master? Thread.current.thread_variable_get(:active_record_slave) == :master end |
.read_from_slave ⇒ Object
The default behavior can also set to read/write operations against master Create an initializer file config/initializer/active_record_slave.rb and set ActiveRecordSlave.read_from_master! to force read from master. Then use this method and supply block to read from the slave database Only applies to calls made within the current thread
59 60 61 62 63 64 65 66 67 68 |
# File 'lib/active_record_slave/active_record_slave.rb', line 59 def self.read_from_slave return yield if read_from_slave? begin previous = Thread.current.thread_variable_get(:active_record_slave) read_from_slave! yield ensure Thread.current.thread_variable_set(:active_record_slave, previous) end end |
.read_from_slave! ⇒ Object
Subsequent reads on this thread and any fibers called by this thread can go to a slave
112 113 114 |
# File 'lib/active_record_slave/active_record_slave.rb', line 112 def self.read_from_slave! Thread.current.thread_variable_set(:active_record_slave, nil) end |
.read_from_slave? ⇒ Boolean
Whether this thread is currently forcing all reads to go against the slave database
102 103 104 |
# File 'lib/active_record_slave/active_record_slave.rb', line 102 def self.read_from_slave? Thread.current.thread_variable_get(:active_record_slave).nil? end |
.skip_transactions ⇒ Object
During this block any attempts to start or end transactions will be ignored. This extreme action should only be taken when 100% certain no writes are going to be performed.
86 87 88 89 90 91 92 93 94 |
# File 'lib/active_record_slave/active_record_slave.rb', line 86 def self.skip_transactions begin previous = Thread.current.thread_variable_get(:active_record_slave_transaction) Thread.current.thread_variable_set(:active_record_slave_transaction, :skip) yield ensure Thread.current.thread_variable_set(:active_record_slave_transaction, previous) end end |
.skip_transactions? ⇒ Boolean
Whether any attempt to start a transaction should be skipped.
122 123 124 |
# File 'lib/active_record_slave/active_record_slave.rb', line 122 def self.skip_transactions? Thread.current.thread_variable_get(:active_record_slave_transaction) == :skip end |