makara 0.5.1 → 0.6.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/CI.yml +0 -4
- data/.rubocop_todo.yml +6 -6
- data/CHANGELOG.md +3 -1
- data/README.md +51 -51
- data/lib/active_record/connection_adapters/makara_abstract_adapter.rb +32 -16
- data/lib/makara/config_parser.rb +63 -104
- data/lib/makara/connection_wrapper.rb +1 -1
- data/lib/makara/context.rb +1 -1
- data/lib/makara/logging/subscriber.rb +1 -1
- data/lib/makara/middleware.rb +1 -1
- data/lib/makara/pool.rb +2 -2
- data/lib/makara/proxy.rb +67 -52
- data/lib/makara/version.rb +5 -3
- data/spec/active_record/connection_adapters/makara_abstract_adapter_error_handling_spec.rb +2 -2
- data/spec/active_record/connection_adapters/makara_abstract_adapter_spec.rb +6 -6
- data/spec/active_record/connection_adapters/makara_mysql2_adapter_spec.rb +28 -26
- data/spec/active_record/connection_adapters/makara_postgis_adapter_spec.rb +15 -15
- data/spec/active_record/connection_adapters/makara_postgresql_adapter_spec.rb +25 -23
- data/spec/config_parser_spec.rb +26 -26
- data/spec/connection_wrapper_spec.rb +2 -2
- data/spec/context_spec.rb +1 -1
- data/spec/middleware_spec.rb +4 -4
- data/spec/pool_spec.rb +9 -9
- data/spec/proxy_spec.rb +74 -74
- data/spec/spec_helper.rb +7 -0
- data/spec/strategies/priority_failover_spec.rb +2 -2
- data/spec/strategies/shard_aware_spec.rb +16 -16
- data/spec/support/helpers.rb +6 -6
- data/spec/support/mock_objects.rb +1 -1
- data/spec/support/mysql2_database.yml +4 -4
- data/spec/support/mysql2_database_with_custom_errors.yml +4 -4
- data/spec/support/postgis_database.yml +4 -4
- data/spec/support/postgresql_database.yml +4 -4
- data/spec/support/proxy_extensions.rb +3 -3
- metadata +5 -5
data/lib/makara/context.rb
CHANGED
@@ -99,7 +99,7 @@ module Makara
|
|
99
99
|
set(:makara_current_context, new(context_data))
|
100
100
|
end
|
101
101
|
|
102
|
-
# Called by `Proxy#
|
102
|
+
# Called by `Proxy#stick_to_primary!` to use primary in subsequent requests
|
103
103
|
def stick(proxy_id, ttl)
|
104
104
|
current.stage(proxy_id, ttl)
|
105
105
|
end
|
@@ -18,7 +18,7 @@ module Makara
|
|
18
18
|
# uses the adapter's connection proxy to modify the name of the event
|
19
19
|
# the name of the used connection will be prepended to the sql log
|
20
20
|
###
|
21
|
-
### [
|
21
|
+
### [Primary|Replica] User Load (1.3ms) SELECT * FROM `users`;
|
22
22
|
###
|
23
23
|
def current_wrapper_name(event)
|
24
24
|
connection_object_id = event.payload[:connection_id]
|
data/lib/makara/middleware.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'rack'
|
2
2
|
|
3
|
-
# Persists the Makara::Context across requests ensuring the same
|
3
|
+
# Persists the Makara::Context across requests ensuring the same primary pool is used on subsequent requests.
|
4
4
|
module Makara
|
5
5
|
class Middleware
|
6
6
|
def initialize(app, cookie_options = {})
|
data/lib/makara/pool.rb
CHANGED
@@ -17,7 +17,7 @@ module Makara
|
|
17
17
|
attr_reader :default_shard
|
18
18
|
|
19
19
|
def initialize(role, proxy)
|
20
|
-
@role = role
|
20
|
+
@role = role == "master" ? "primary" : role
|
21
21
|
@proxy = proxy
|
22
22
|
@connections = []
|
23
23
|
@blacklist_errors = []
|
@@ -125,7 +125,7 @@ module Makara
|
|
125
125
|
# when a connection causes a blacklist error within the provided block, we blacklist it then retry
|
126
126
|
rescue Makara::Errors::BlacklistConnection => e
|
127
127
|
@blacklist_errors.insert(0, e)
|
128
|
-
in_transaction = self.role == "
|
128
|
+
in_transaction = self.role == "primary" && provided_connection._makara_in_transaction?
|
129
129
|
provided_connection._makara_blacklist!
|
130
130
|
raise Makara::Errors::BlacklistedWhileInTransaction.new(@role) if in_transaction
|
131
131
|
|
data/lib/makara/proxy.rb
CHANGED
@@ -3,7 +3,7 @@ require 'active_support/core_ext/class/attribute'
|
|
3
3
|
require 'active_support/core_ext/hash/keys'
|
4
4
|
require 'active_support/core_ext/string/inflections'
|
5
5
|
|
6
|
-
# The entry point of Makara. It contains a
|
6
|
+
# The entry point of Makara. It contains a primary and replica pool which are chosen based on the invocation
|
7
7
|
# being proxied. Makara::Proxy implementations should declare which methods they are hijacking via the
|
8
8
|
# `hijack_method` class method.
|
9
9
|
# While debugging this class use prepend debug calls with Kernel. (Kernel.byebug for example)
|
@@ -66,7 +66,7 @@ module Makara
|
|
66
66
|
@config = config.symbolize_keys
|
67
67
|
@config_parser = Makara::ConfigParser.new(@config)
|
68
68
|
@id = @config_parser.id
|
69
|
-
@ttl = @config_parser.makara_config[:
|
69
|
+
@ttl = @config_parser.makara_config[:primary_ttl]
|
70
70
|
@sticky = @config_parser.makara_config[:sticky]
|
71
71
|
@hijacked = false
|
72
72
|
@error_handler ||= ::Makara::ErrorHandler.new
|
@@ -86,13 +86,18 @@ module Makara
|
|
86
86
|
@hijacked
|
87
87
|
end
|
88
88
|
|
89
|
-
# If persist is true, we stick the proxy to
|
90
|
-
# up to
|
91
|
-
def
|
89
|
+
# If persist is true, we stick the proxy to primary for subsequent requests
|
90
|
+
# up to primary_ttl duration. Otherwise we just stick it for the current request
|
91
|
+
def stick_to_primary!(persist = true)
|
92
92
|
stickiness_duration = persist ? @ttl : 0
|
93
93
|
Makara::Context.stick(@id, stickiness_duration)
|
94
94
|
end
|
95
95
|
|
96
|
+
def stick_to_master!(persist = true)
|
97
|
+
warn "#{self.class}.stick_to_master! is deprecated. Switch to #stick_to_primary!"
|
98
|
+
stick_to_primary!(persist)
|
99
|
+
end
|
100
|
+
|
96
101
|
def strategy_for(role)
|
97
102
|
strategy_class_for(strategy_name_for(role)).new(self)
|
98
103
|
end
|
@@ -162,33 +167,33 @@ module Makara
|
|
162
167
|
protected
|
163
168
|
|
164
169
|
def send_to_all(method_name, *args)
|
165
|
-
#
|
170
|
+
# replica pool must run first to allow for replica --> primary failover without running operations on the primary twice.
|
166
171
|
handling_an_all_execution(method_name) do
|
167
|
-
@
|
168
|
-
@
|
172
|
+
@replica_pool.send_to_all(method_name, *args)
|
173
|
+
@primary_pool.send_to_all(method_name, *args)
|
169
174
|
end
|
170
175
|
end
|
171
176
|
|
172
177
|
ruby2_keywords :send_to_all if Module.private_method_defined?(:ruby2_keywords)
|
173
178
|
|
174
179
|
def any_connection
|
175
|
-
if @
|
176
|
-
@
|
180
|
+
if @primary_pool.disabled
|
181
|
+
@replica_pool.provide do |con|
|
177
182
|
yield con
|
178
183
|
end
|
179
184
|
else
|
180
|
-
@
|
185
|
+
@primary_pool.provide do |con|
|
181
186
|
yield con
|
182
187
|
end
|
183
188
|
end
|
184
189
|
rescue ::Makara::Errors::AllConnectionsBlacklisted, ::Makara::Errors::NoConnectionsAvailable
|
185
190
|
begin
|
186
|
-
@
|
187
|
-
@
|
191
|
+
@primary_pool.disabled = true
|
192
|
+
@replica_pool.provide do |con|
|
188
193
|
yield con
|
189
194
|
end
|
190
195
|
ensure
|
191
|
-
@
|
196
|
+
@primary_pool.disabled = false
|
192
197
|
end
|
193
198
|
end
|
194
199
|
|
@@ -205,52 +210,57 @@ module Makara
|
|
205
210
|
end
|
206
211
|
end
|
207
212
|
|
208
|
-
#
|
213
|
+
# primary or replica
|
209
214
|
def appropriate_pool(method_name, args)
|
210
215
|
# for testing purposes
|
211
216
|
pool = _appropriate_pool(method_name, args)
|
212
217
|
yield pool
|
213
218
|
rescue ::Makara::Errors::AllConnectionsBlacklisted, ::Makara::Errors::NoConnectionsAvailable => e
|
214
|
-
if pool == @
|
215
|
-
@
|
216
|
-
@
|
219
|
+
if pool == @primary_pool
|
220
|
+
@primary_pool.connections.each(&:_makara_whitelist!)
|
221
|
+
@replica_pool.connections.each(&:_makara_whitelist!)
|
217
222
|
Kernel.raise e
|
218
223
|
else
|
219
|
-
@
|
224
|
+
@primary_pool.blacklist_errors << e
|
220
225
|
retry
|
221
226
|
end
|
222
227
|
end
|
223
228
|
|
224
229
|
def _appropriate_pool(method_name, args)
|
225
|
-
# the args provided absolutely need
|
226
|
-
if
|
227
|
-
|
228
|
-
@
|
230
|
+
# the args provided absolutely need primary
|
231
|
+
if needs_primary?(method_name, args)
|
232
|
+
stick_to_primary(method_name, args)
|
233
|
+
@primary_pool
|
229
234
|
|
230
|
-
elsif
|
235
|
+
elsif stuck_to_primary?
|
231
236
|
|
232
|
-
# we're on
|
237
|
+
# we're on primary because we already stuck this proxy in this
|
233
238
|
# request or because we got stuck in previous requests and the
|
234
239
|
# stickiness is still valid
|
235
|
-
@
|
240
|
+
@primary_pool
|
236
241
|
|
237
|
-
# all
|
238
|
-
elsif @
|
239
|
-
|
240
|
-
@
|
242
|
+
# all replicas are down (or empty)
|
243
|
+
elsif @replica_pool.completely_blacklisted?
|
244
|
+
stick_to_primary(method_name, args)
|
245
|
+
@primary_pool
|
241
246
|
|
242
247
|
elsif in_transaction?
|
243
|
-
@
|
248
|
+
@primary_pool
|
244
249
|
|
245
|
-
# yay! use a
|
250
|
+
# yay! use a replica
|
246
251
|
else
|
247
|
-
@
|
252
|
+
@replica_pool
|
248
253
|
end
|
249
254
|
end
|
250
255
|
|
251
|
-
#
|
252
|
-
def
|
253
|
-
|
256
|
+
# Do these args require a primary connection
|
257
|
+
def needs_primary?(method_name, args)
|
258
|
+
if respond_to?(:needs_master?)
|
259
|
+
warn "#{self.class}#needs_master? is deprecated. Switch to #needs_primary?"
|
260
|
+
needs_master?(method_name, args)
|
261
|
+
else
|
262
|
+
true
|
263
|
+
end
|
254
264
|
end
|
255
265
|
|
256
266
|
def in_transaction?
|
@@ -268,16 +278,21 @@ module Makara
|
|
268
278
|
@hijacked = false
|
269
279
|
end
|
270
280
|
|
271
|
-
def
|
281
|
+
def stuck_to_primary?
|
272
282
|
sticky? && Makara::Context.stuck?(@id)
|
273
283
|
end
|
274
284
|
|
275
|
-
def
|
285
|
+
def stick_to_primary(method_name, args)
|
276
286
|
# check to see if we're configured, bypassed, or some custom implementation has input
|
277
287
|
return unless should_stick?(method_name, args)
|
278
288
|
|
279
289
|
# do the sticking
|
280
|
-
|
290
|
+
stick_to_primary!
|
291
|
+
end
|
292
|
+
|
293
|
+
def stick_to_master(method_names, args)
|
294
|
+
warn "#{self.class}#stick_to_master is deprecated. Switch to #stick_to_primary"
|
295
|
+
stick_to_primary(method_names, args)
|
281
296
|
end
|
282
297
|
|
283
298
|
# For the generic proxy implementation, we stick if we are sticky,
|
@@ -291,19 +306,19 @@ module Makara
|
|
291
306
|
@sticky && !@skip_sticking
|
292
307
|
end
|
293
308
|
|
294
|
-
# use the config parser to generate a
|
309
|
+
# use the config parser to generate a primary and replica pool
|
295
310
|
def instantiate_connections
|
296
|
-
@
|
297
|
-
@config_parser.
|
298
|
-
@
|
299
|
-
graceful_connection_for(
|
311
|
+
@primary_pool = Makara::Pool.new('primary', self)
|
312
|
+
@config_parser.primary_configs.each do |primary_config|
|
313
|
+
@primary_pool.add primary_config do
|
314
|
+
graceful_connection_for(primary_config)
|
300
315
|
end
|
301
316
|
end
|
302
317
|
|
303
|
-
@
|
304
|
-
@config_parser.
|
305
|
-
@
|
306
|
-
graceful_connection_for(
|
318
|
+
@replica_pool = Makara::Pool.new('replica', self)
|
319
|
+
@config_parser.replica_configs.each do |replica_config|
|
320
|
+
@replica_pool.add replica_config do
|
321
|
+
graceful_connection_for(replica_config)
|
307
322
|
end
|
308
323
|
end
|
309
324
|
end
|
@@ -311,15 +326,15 @@ module Makara
|
|
311
326
|
def handling_an_all_execution(method_name)
|
312
327
|
yield
|
313
328
|
rescue ::Makara::Errors::NoConnectionsAvailable => e
|
314
|
-
if e.role == '
|
315
|
-
# this means
|
329
|
+
if e.role == 'primary'
|
330
|
+
# this means replica connections are good.
|
316
331
|
return
|
317
332
|
end
|
318
333
|
|
319
|
-
@
|
334
|
+
@replica_pool.disabled = true
|
320
335
|
yield
|
321
336
|
ensure
|
322
|
-
@
|
337
|
+
@replica_pool.disabled = false
|
323
338
|
end
|
324
339
|
|
325
340
|
def connection_for(config)
|
data/lib/makara/version.rb
CHANGED
@@ -4,7 +4,7 @@ require 'active_record/connection_adapters/makara_abstract_adapter'
|
|
4
4
|
describe ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter::ErrorHandler do
|
5
5
|
let(:handler){ described_class.new }
|
6
6
|
let(:proxy) { FakeAdapter.new(config(1,1)) }
|
7
|
-
let(:connection){ proxy.
|
7
|
+
let(:connection){ proxy.primary_pool.connections.first }
|
8
8
|
|
9
9
|
[
|
10
10
|
%|Mysql::Error: : INSERT INTO `watchers` (`user_id`, `watchable_id`, `watchable_type`) VALUES|,
|
@@ -63,7 +63,7 @@ describe ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter::ErrorHandler d
|
|
63
63
|
let(:config) { YAML.load(ERB.new(File.read(config_path)).result)['test'] }
|
64
64
|
let(:handler){ described_class.new }
|
65
65
|
let(:proxy) { FakeAdapter.new(config) }
|
66
|
-
let(:connection){ proxy.
|
66
|
+
let(:connection){ proxy.primary_pool.connections.first }
|
67
67
|
let(:msg1) { "ActiveRecord::StatementInvalid: Mysql2::Error: Unknown command1: SELECT `users`.* FROM `users` WHERE `users`.`id` = 53469 LIMIT 1" }
|
68
68
|
let(:msg2) { "activeRecord::statementInvalid: mysql2::error: unknown command2: SELECT `users`.* FROM `users` WHERE `users`.`id` = 53469 LIMIT 1" }
|
69
69
|
let(:msg3) { "ActiveRecord::StatementInvalid: Mysql2::Error: Unknown command3: SELECT `users`.* FROM `users` WHERE `users`.`id` = 53469 LIMIT 1" }
|
@@ -36,10 +36,10 @@ describe ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter do
|
|
36
36
|
'select release_lock(\'foo\')' => true,
|
37
37
|
'select pg_advisory_lock(12345)' => true,
|
38
38
|
'select pg_advisory_unlock(12345)' => true
|
39
|
-
}.each do |sql,
|
40
|
-
it "determines that \"#{sql}\" #{
|
39
|
+
}.each do |sql, should_go_to_primary|
|
40
|
+
it "determines that \"#{sql}\" #{should_go_to_primary ? 'requires' : 'does not require'} primary" do
|
41
41
|
proxy = klass.new(config(1,1))
|
42
|
-
expect(proxy.
|
42
|
+
expect(proxy.primary_for?(sql)).to eq(should_go_to_primary)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -59,8 +59,8 @@ describe ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter do
|
|
59
59
|
}.each do |sql, should_send_to_all_connections|
|
60
60
|
it "determines that \"#{sql}\" #{should_send_to_all_connections ? 'should' : 'should not'} be sent to all underlying connections" do
|
61
61
|
proxy = klass.new(config(1,1))
|
62
|
-
proxy.
|
63
|
-
proxy.
|
62
|
+
proxy.primary_pool.connections.each{|con| expect(con).to receive(:execute).with(sql).once}
|
63
|
+
proxy.replica_pool.connections.each do |con|
|
64
64
|
if should_send_to_all_connections
|
65
65
|
expect(con).to receive(:execute).with(sql).once
|
66
66
|
else
|
@@ -102,7 +102,7 @@ describe ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter do
|
|
102
102
|
max_treats IS NULL
|
103
103
|
} => true
|
104
104
|
}.each do |sql,should_stick|
|
105
|
-
it "should #{should_stick ? 'stick' : 'not stick'} to
|
105
|
+
it "should #{should_stick ? 'stick' : 'not stick'} to primary if handling sql like \"#{sql}\"" do
|
106
106
|
proxy = klass.new(config(0,0))
|
107
107
|
expect(proxy.would_stick?(sql)).to eq(should_stick)
|
108
108
|
end
|
@@ -21,17 +21,17 @@ describe 'MakaraMysql2Adapter' do
|
|
21
21
|
expect(ActiveRecord::Base.connection).to be_instance_of(ActiveRecord::ConnectionAdapters::MakaraMysql2Adapter)
|
22
22
|
end
|
23
23
|
|
24
|
-
it 'should execute a send_to_all against
|
24
|
+
it 'should execute a send_to_all against primary even if no replicas are connected' do
|
25
25
|
establish_connection(config)
|
26
26
|
connection = ActiveRecord::Base.connection
|
27
27
|
|
28
|
-
connection.
|
28
|
+
connection.replica_pool.connections.each do |c|
|
29
29
|
allow(c).to receive(:_makara_blacklisted?){ true }
|
30
30
|
allow(c).to receive(:_makara_connected?){ false }
|
31
31
|
expect(c).to receive(:execute).with('SET @t1 = 1').never
|
32
32
|
end
|
33
33
|
|
34
|
-
connection.
|
34
|
+
connection.primary_pool.connections.each do |c|
|
35
35
|
expect(c).to receive(:execute).with('SET @t1 = 1')
|
36
36
|
end
|
37
37
|
|
@@ -44,7 +44,7 @@ describe 'MakaraMysql2Adapter' do
|
|
44
44
|
establish_connection(config)
|
45
45
|
connection = ActiveRecord::Base.connection
|
46
46
|
|
47
|
-
(connection.
|
47
|
+
(connection.replica_pool.connections | connection.primary_pool.connections).each do |c|
|
48
48
|
allow(c).to receive(:_makara_blacklisted?){ true }
|
49
49
|
allow(c).to receive(:_makara_connected?){ false }
|
50
50
|
expect(c).to receive(:execute).with('SET @t1 = 1').never
|
@@ -62,7 +62,7 @@ describe 'MakaraMysql2Adapter' do
|
|
62
62
|
|
63
63
|
it 'should not blow up if a connection fails' do
|
64
64
|
wrong_config = config.deep_dup
|
65
|
-
wrong_config['makara']['connections'].select{|h| h['role'] == '
|
65
|
+
wrong_config['makara']['connections'].select{|h| h['role'] == 'replica' }.each{|h| h['username'] = 'other'}
|
66
66
|
|
67
67
|
original_method = ActiveRecord::Base.method(:mysql2_connection)
|
68
68
|
|
@@ -84,8 +84,8 @@ describe 'MakaraMysql2Adapter' do
|
|
84
84
|
original_method.call(config)
|
85
85
|
end
|
86
86
|
|
87
|
-
ActiveRecord::Base.connection.
|
88
|
-
ActiveRecord::Base.connection.
|
87
|
+
ActiveRecord::Base.connection.replica_pool.connections.each(&:_makara_whitelist!)
|
88
|
+
ActiveRecord::Base.connection.replica_pool.provide do |con|
|
89
89
|
res = con.execute('SELECT count(*) FROM users')
|
90
90
|
if defined?(JRUBY_VERSION)
|
91
91
|
expect(res[0]).to eq('count(*)' => 0)
|
@@ -106,16 +106,16 @@ describe 'MakaraMysql2Adapter' do
|
|
106
106
|
change_context
|
107
107
|
end
|
108
108
|
|
109
|
-
it 'should have one
|
110
|
-
expect(connection.
|
111
|
-
expect(connection.
|
109
|
+
it 'should have one primary and two replicas' do
|
110
|
+
expect(connection.primary_pool.connection_count).to eq(1)
|
111
|
+
expect(connection.replica_pool.connection_count).to eq(2)
|
112
112
|
end
|
113
113
|
|
114
114
|
it 'should allow real queries to work' do
|
115
115
|
connection.execute("INSERT INTO users (name) VALUES ('John')")
|
116
116
|
|
117
|
-
connection.
|
118
|
-
expect(
|
117
|
+
connection.primary_pool.connections.each do |primary|
|
118
|
+
expect(primary).to receive(:execute).never
|
119
119
|
end
|
120
120
|
|
121
121
|
change_context
|
@@ -130,40 +130,42 @@ describe 'MakaraMysql2Adapter' do
|
|
130
130
|
end
|
131
131
|
|
132
132
|
it 'should send SET operations to each connection' do
|
133
|
-
connection.
|
133
|
+
connection.primary_pool.connections.each do |con|
|
134
134
|
expect(con).to receive(:execute).with('SET @t1 = 1').once
|
135
135
|
end
|
136
136
|
|
137
|
-
connection.
|
137
|
+
connection.replica_pool.connections.each do |con|
|
138
138
|
expect(con).to receive(:execute).with('SET @t1 = 1').once
|
139
139
|
end
|
140
140
|
connection.execute("SET @t1 = 1")
|
141
141
|
end
|
142
142
|
|
143
|
-
it 'should send reads to the
|
143
|
+
it 'should send reads to the replica' do
|
144
144
|
# ensure the next connection will be the first one
|
145
145
|
allow_any_instance_of(Makara::Strategies::RoundRobin).to receive(:single_one?){ true }
|
146
146
|
|
147
|
-
con = connection.
|
147
|
+
con = connection.replica_pool.connections.first
|
148
148
|
expect(con).to receive(:execute).with('SELECT * FROM users').once
|
149
149
|
|
150
150
|
connection.execute('SELECT * FROM users')
|
151
151
|
end
|
152
152
|
|
153
|
-
it 'should send exists? to
|
153
|
+
it 'should send exists? to replica' do
|
154
154
|
allow_any_instance_of(Makara::Strategies::RoundRobin).to receive(:single_one?){ true }
|
155
155
|
Test::User.exists? # flush other (schema) things that need to happen
|
156
156
|
|
157
|
-
con = connection.
|
157
|
+
con = connection.replica_pool.connections.first
|
158
158
|
expect(con).to receive(:exec_query) do |query|
|
159
159
|
expect(query).to match(/SELECT\s+1\s*(AS one)?\s+FROM .?users.?\s+LIMIT\s+.?1/)
|
160
|
-
end.once.
|
160
|
+
end.once.
|
161
|
+
# and_call_original # Switch back to this once https://github.com/rspec/rspec-mocks/pull/1385 is released
|
162
|
+
and_wrap_original { |m, *args| m.call(*args.first(3)) }
|
161
163
|
|
162
164
|
Test::User.exists?
|
163
165
|
end
|
164
166
|
|
165
|
-
it 'should send writes to
|
166
|
-
con = connection.
|
167
|
+
it 'should send writes to primary' do
|
168
|
+
con = connection.primary_pool.connections.first
|
167
169
|
expect(con).to receive(:execute).with('UPDATE users SET name = "bob" WHERE id = 1')
|
168
170
|
connection.execute('UPDATE users SET name = "bob" WHERE id = 1')
|
169
171
|
end
|
@@ -174,7 +176,7 @@ describe 'MakaraMysql2Adapter' do
|
|
174
176
|
end
|
175
177
|
|
176
178
|
it 'should allow reconnecting when one of the nodes is blacklisted' do
|
177
|
-
con = connection.
|
179
|
+
con = connection.replica_pool.connections.first
|
178
180
|
allow(con).to receive(:_makara_blacklisted?){ true }
|
179
181
|
connection.reconnect!
|
180
182
|
end
|
@@ -196,11 +198,11 @@ describe 'MakaraMysql2Adapter' do
|
|
196
198
|
load(File.dirname(__FILE__) + '/../../support/schema.rb')
|
197
199
|
change_context
|
198
200
|
|
199
|
-
connection.
|
201
|
+
connection.replica_pool.connections.each do |replica|
|
200
202
|
# Using method missing to help with back trace, literally
|
201
|
-
# no query should be executed on
|
202
|
-
expect(
|
203
|
-
expect(
|
203
|
+
# no query should be executed on replica once a transaction is opened
|
204
|
+
expect(replica).to receive(:method_missing).never
|
205
|
+
expect(replica).to receive(:execute).never
|
204
206
|
end
|
205
207
|
end
|
206
208
|
|