Module: ActiveRecord::ConnectionAdapters::MasterSlaveAdapter
- Included in:
- Mysql2MasterSlaveAdapter, MysqlMasterSlaveAdapter
- Defined in:
- lib/active_record/connection_adapters/master_slave_adapter.rb,
lib/active_record/connection_adapters/master_slave_adapter/clock.rb,
lib/active_record/connection_adapters/master_slave_adapter/version.rb,
lib/active_record/connection_adapters/master_slave_adapter/circuit_breaker.rb,
lib/active_record/connection_adapters/master_slave_adapter/shared_mysql_adapter_behavior.rb
Defined Under Namespace
Modules: SharedMysqlAdapterBehavior
Classes: CircuitBreaker, Clock
Constant Summary
collapse
- VERSION =
"1.1.2"
Class Method Summary
collapse
Instance Method Summary
collapse
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &blk) ⇒ Object
ok, we might have missed more
326
327
328
329
330
331
332
333
334
335
336
337
338
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 326
def method_missing(name, *args, &blk)
master_connection.send(name.to_sym, *args, &blk).tap do
@logger.try(:warn, %Q{
You called the unsupported method '#{name}' on #{self.class.name}.
In order to help us improve master_slave_adapter, please report this
to: https://github.com/soundcloud/master_slave_adapter/issues
Thank you.
})
end
rescue ActiveRecord::StatementInvalid => exception
handle_error(master_connection, exception)
end
|
Class Method Details
.rescued_delegate(*methods) ⇒ Object
ADAPTER INTERFACE DELEGATES ===========================================
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 219
def self.rescued_delegate(*methods)
options = methods.pop
to = options[:to]
file, line = caller.first.split(':', 2)
line = line.to_i
methods.each do |method|
module_eval(<<-EOS, file, line)
def #{method}(*args, &block)
begin
#{to}.__send__(:#{method}, *args, &block)
rescue ActiveRecord::StatementInvalid => error
handle_error(#{to}, error)
end
end
EOS
end
end
|
Instance Method Details
#active? ⇒ Boolean
180
181
182
183
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 180
def active?
return true if @disable_connection_test
connections.map { |c| c.active? }.all?
end
|
#cache(&blk) ⇒ Object
197
198
199
200
201
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 197
def cache(&blk)
connections.inject(blk) do |block, connection|
lambda { connection.cache(&block) }
end.call
end
|
#clear_query_cache ⇒ Object
209
210
211
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 209
def clear_query_cache
connections.each { |connection| connection.clear_query_cache }
end
|
#commit_db_transaction ⇒ Object
169
170
171
172
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 169
def commit_db_transaction
on_write { |conn| conn.commit_db_transaction }
on_commit_callbacks.shift.call(current_clock) until on_commit_callbacks.blank?
end
|
#connections ⇒ Object
367
368
369
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 367
def connections
@connections.values.flatten.compact
end
|
#current_clock ⇒ Object
375
376
377
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 375
def current_clock
@master_slave_clock
end
|
#current_connection ⇒ Object
371
372
373
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 371
def current_connection
connection_stack.first
end
|
#delete(*args) ⇒ Object
161
162
163
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 161
def delete(*args)
on_write { |conn| conn.delete(*args) }
end
|
#disconnect! ⇒ Object
189
190
191
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 189
def disconnect!
connections.each { |c| c.disconnect! }
end
|
#execute(*args) ⇒ Object
165
166
167
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 165
def execute(*args)
on_write { |conn| conn.execute(*args) }
end
|
#initialize(config, logger) ⇒ Object
100
101
102
103
104
105
106
107
108
109
110
111
112
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 100
def initialize(config, logger)
super(nil, logger)
@config = config
@connections = {}
@connections[:master] = connect_to_master
@connections[:slaves] = @config.fetch(:slaves).map { |cfg| connect(cfg, :slave) }
@last_seen_slave_clocks = {}
@disable_connection_test = @config[:disable_connection_test] == 'true'
@circuit = CircuitBreaker.new(logger)
self.current_connection = slave_connection!
end
|
#insert(*args) ⇒ Object
ADAPTER INTERFACE OVERRIDES ===========================================
153
154
155
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 153
def insert(*args)
on_write { |conn| conn.insert(*args) }
end
|
#master_available? ⇒ Boolean
357
358
359
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 357
def master_available?
!@connections[:master].nil?
end
|
#master_clock ⇒ Object
379
380
381
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 379
def master_clock
raise NotImplementedError
end
|
#master_connection ⇒ Object
UTIL ==================================================================
342
343
344
345
346
347
348
349
350
351
352
353
354
355
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 342
def master_connection
if circuit.tripped?
raise MasterUnavailable
end
@connections[:master] ||= connect_to_master
if @connections[:master]
circuit.success!
@connections[:master]
else
circuit.fail!
raise MasterUnavailable
end
end
|
#on_commit(&blk) ⇒ Object
143
144
145
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 143
def on_commit(&blk)
on_commit_callbacks.push blk
end
|
#on_rollback(&blk) ⇒ Object
147
148
149
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 147
def on_rollback(&blk)
on_rollback_callbacks.push blk
end
|
#outside_transaction? ⇒ Boolean
213
214
215
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 213
def outside_transaction?
nil
end
|
#reconnect! ⇒ Object
185
186
187
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 185
def reconnect!
connections.each { |c| c.reconnect! }
end
|
#reset! ⇒ Object
193
194
195
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 193
def reset!
connections.each { |c| c.reset! }
end
|
#rollback_db_transaction ⇒ Object
174
175
176
177
178
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 174
def rollback_db_transaction
on_commit_callbacks.clear
with(master_connection) { |conn| conn.rollback_db_transaction }
on_rollback_callbacks.shift.call until on_rollback_callbacks.blank?
end
|
#slave_clock(conn) ⇒ Object
383
384
385
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 383
def slave_clock(conn)
raise NotImplementedError
end
|
#slave_connection! ⇒ Object
Returns a random slave connection Note: the method is not referentially transparent, hence the bang
363
364
365
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 363
def slave_connection!
@connections[:slaves].sample
end
|
#uncached(&blk) ⇒ Object
203
204
205
206
207
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 203
def uncached(&blk)
connections.inject(blk) do |block, connection|
lambda { connection.uncached(&block) }
end.call
end
|
#update(*args) ⇒ Object
157
158
159
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 157
def update(*args)
on_write { |conn| conn.update(*args) }
end
|
#with_consistency(clock) ⇒ Object
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 124
def with_consistency(clock)
if clock.nil?
raise ArgumentError, "consistency must be a valid comparable value"
end
slave = slave_connection!
conn =
if !open_transaction? && slave_consistent?(slave, clock)
slave
else
master_connection
end
with(conn) { yield }
current_clock || clock
end
|
#with_master ⇒ Object
MASTER SLAVE ADAPTER INTERFACE ========================================
116
117
118
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 116
def with_master
with(master_connection) { yield }
end
|
#with_slave ⇒ Object
120
121
122
|
# File 'lib/active_record/connection_adapters/master_slave_adapter.rb', line 120
def with_slave
with(slave_connection!) { yield }
end
|