Class: ActiveRecord::ConnectionAdapters::MasterSlaveAdapter

Inherits:
Object
  • Object
show all
Includes:
ActiveSupport::Callbacks
Defined in:
lib/master_slave_adapter/adapter.rb

Defined Under Namespace

Classes: Clock

Constant Summary collapse

SELECT_METHODS =
[ :select_all, :select_one, :select_rows, :select_value, :select_values ]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config) ⇒ MasterSlaveAdapter

Returns a new instance of MasterSlaveAdapter.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/master_slave_adapter/adapter.rb', line 38

def initialize( config )
  if config[:master].blank?
    raise "There is no :master config in the database configuration provided -> #{config.inspect} "
  end
  self.slave_config = config.symbolize_keys
  self.master_config = self.slave_config.delete(:master).symbolize_keys
  self.slave_config[:adapter] = self.slave_config.delete(:master_slave_adapter)
  self.master_config[:adapter] ||= self.slave_config[:adapter]
  self.disable_connection_test = self.slave_config.delete( :disable_connection_test ) == 'true'
  self.connections = []
  if self.slave_config.delete( :eager_load_connections ) == 'true'
    connect_to_master
    connect_to_slave
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object



86
87
88
# File 'lib/master_slave_adapter/adapter.rb', line 86

def method_missing( name, *args, &block )
  self.master_connection.send( name.to_sym, *args, &block )
end

Instance Attribute Details

#connectionsObject

Returns the value of attribute connections.



30
31
32
# File 'lib/master_slave_adapter/adapter.rb', line 30

def connections
  @connections
end

#disable_connection_testObject

Returns the value of attribute disable_connection_test.



33
34
35
# File 'lib/master_slave_adapter/adapter.rb', line 33

def disable_connection_test
  @disable_connection_test
end

#master_configObject

Returns the value of attribute master_config.



31
32
33
# File 'lib/master_slave_adapter/adapter.rb', line 31

def master_config
  @master_config
end

#slave_configObject

Returns the value of attribute slave_config.



32
33
34
# File 'lib/master_slave_adapter/adapter.rb', line 32

def slave_config
  @slave_config
end

Class Method Details

.master_forced=(state) ⇒ Object



183
184
185
# File 'lib/master_slave_adapter/adapter.rb', line 183

def master_forced=(state)
  Thread.current[:master_slave_enabled] = state ? true : nil
end

.master_forced?Boolean

Returns:

  • (Boolean)


179
180
181
# File 'lib/master_slave_adapter/adapter.rb', line 179

def master_forced?
  Thread.current[:master_slave_enabled] == true
end

.reset!Object



174
175
176
177
# File 'lib/master_slave_adapter/adapter.rb', line 174

def reset!
  Thread.current[:master_slave_connection] = nil
  Thread.current[:master_slave_clock] = nil
end

.using_master?Boolean

Returns:

  • (Boolean)


187
188
189
190
191
192
193
194
# File 'lib/master_slave_adapter/adapter.rb', line 187

def using_master?
  if Thread.current[:master_slave_connection]
    Thread.current[:master_slave_connection][0] == :master
  else
    # there is no wrapper so selects go to slave by default
    false
  end
end

.with_consistency(clock, &block) ⇒ Object



170
171
172
# File 'lib/master_slave_adapter/adapter.rb', line 170

def with_consistency(clock, &block)
  ActiveRecord::Base.with_consistency(clock, &block)
end

.with_master(&block) ⇒ Object



162
163
164
# File 'lib/master_slave_adapter/adapter.rb', line 162

def with_master(&block)
  ActiveRecord::Base.with_master(&block)
end

.with_slave(&block) ⇒ Object



166
167
168
# File 'lib/master_slave_adapter/adapter.rb', line 166

def with_slave(&block)
  ActiveRecord::Base.with_slave(&block)
end

Instance Method Details

#current_clockObject



110
111
112
# File 'lib/master_slave_adapter/adapter.rb', line 110

def current_clock
  Thread.current[:master_slave_clock] || []
end

#current_clock=(stack) ⇒ Object



106
107
108
# File 'lib/master_slave_adapter/adapter.rb', line 106

def current_clock=(stack)
  Thread.current[:master_slave_clock] = stack
end

#current_connectionObject



102
103
104
# File 'lib/master_slave_adapter/adapter.rb', line 102

def current_connection
  Thread.current[:master_slave_connection] || []
end

#current_connection=(stack) ⇒ Object



98
99
100
# File 'lib/master_slave_adapter/adapter.rb', line 98

def current_connection=(stack)
  Thread.current[:master_slave_connection] = stack
end

#delete(sql, *args) ⇒ Object



66
67
68
69
70
# File 'lib/master_slave_adapter/adapter.rb', line 66

def delete(sql, *args)
  on_write do
    self.master_connection.delete(sql, *args)
  end
end

#disconnect!Object



77
78
79
80
# File 'lib/master_slave_adapter/adapter.rb', line 77

def disconnect!
  @active = false
  self.connections.each { |c| c.disconnect! }
end

#insert(sql, *args) ⇒ Object



54
55
56
57
58
# File 'lib/master_slave_adapter/adapter.rb', line 54

def insert(sql, *args)
  on_write do
    self.master_connection.insert(sql, *args)
  end
end

#master_connectionObject



90
91
92
# File 'lib/master_slave_adapter/adapter.rb', line 90

def master_connection
  connect_to_master
end

#reconnect!Object



72
73
74
75
# File 'lib/master_slave_adapter/adapter.rb', line 72

def reconnect!
  @active = true
  self.connections.each { |c| c.reconnect! }
end

#reset!Object



82
83
84
# File 'lib/master_slave_adapter/adapter.rb', line 82

def reset!
  self.connections.each { |c| c.reset! }
end

#slave_connectionObject



94
95
96
# File 'lib/master_slave_adapter/adapter.rb', line 94

def slave_connection
  connect_to_slave
end

#test_connectionsObject



118
119
120
121
122
123
124
125
126
127
# File 'lib/master_slave_adapter/adapter.rb', line 118

def test_connections
  return if self.disable_connection_test
  self.connections.each do |c|
    begin
      c.select_value( 'SELECT 1', 'test select' )
    rescue
      c.reconnect!
    end
  end
end

#transaction(options = {}, &block) ⇒ Object



154
155
156
157
158
# File 'lib/master_slave_adapter/adapter.rb', line 154

def transaction(options = {}, &block)
  on_write do
    self.master_connection.transaction(options, &block)
  end
end

#update(sql, *args) ⇒ Object



60
61
62
63
64
# File 'lib/master_slave_adapter/adapter.rb', line 60

def update(sql, *args)
  on_write do
    self.master_connection.update(sql, *args)
  end
end

#with_consistency(clock) ⇒ Object

Raises:

  • (ArgumentError)


143
144
145
146
147
148
149
150
151
152
# File 'lib/master_slave_adapter/adapter.rb', line 143

def with_consistency(clock)
  raise ArgumentError, "consistency cannot be nil" if clock.nil?
  self.current_connection = [ nil ] + self.current_connection
  self.current_clock = [ clock ] + self.current_clock
  yield
  result = current_clock[0]
  self.current_clock = self.current_clock.drop(1)
  self.current_connection = self.current_connection.drop(1)
  result
end

#with_masterObject



129
130
131
132
133
134
# File 'lib/master_slave_adapter/adapter.rb', line 129

def with_master
  self.current_connection = [ :master ] + self.current_connection
  result = yield
  self.current_connection = self.current_connection.drop(1)
  result
end

#with_slaveObject



136
137
138
139
140
141
# File 'lib/master_slave_adapter/adapter.rb', line 136

def with_slave
  self.current_connection = [ :slave ] + self.current_connection
  result = yield
  self.current_connection = self.current_connection.drop(1)
  result
end