makara 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +11 -0
- data/.github/workflows/CI.yml +88 -0
- data/.rspec +1 -1
- data/.rubocop.yml +15 -0
- data/.rubocop_todo.yml +670 -0
- data/CHANGELOG.md +14 -6
- data/Gemfile +1 -16
- data/README.md +2 -1
- data/Rakefile +1 -1
- data/gemfiles/activerecord_5.2.gemfile +8 -0
- data/gemfiles/activerecord_6.0.gemfile +8 -0
- data/gemfiles/activerecord_6.1.gemfile +8 -0
- data/gemfiles/activerecord_head.gemfile +6 -0
- data/lib/active_record/connection_adapters/jdbcmysql_makara_adapter.rb +4 -18
- data/lib/active_record/connection_adapters/jdbcpostgresql_makara_adapter.rb +4 -18
- data/lib/active_record/connection_adapters/makara_abstract_adapter.rb +3 -31
- data/lib/active_record/connection_adapters/makara_jdbcmysql_adapter.rb +4 -18
- data/lib/active_record/connection_adapters/makara_jdbcpostgresql_adapter.rb +4 -18
- data/lib/active_record/connection_adapters/makara_mysql2_adapter.rb +4 -20
- data/lib/active_record/connection_adapters/makara_postgis_adapter.rb +4 -19
- data/lib/active_record/connection_adapters/makara_postgresql_adapter.rb +4 -20
- data/lib/active_record/connection_adapters/mysql2_makara_adapter.rb +4 -20
- data/lib/active_record/connection_adapters/postgresql_makara_adapter.rb +4 -20
- data/lib/makara.rb +0 -2
- data/lib/makara/cache.rb +0 -2
- data/lib/makara/config_parser.rb +5 -14
- data/lib/makara/connection_wrapper.rb +24 -27
- data/lib/makara/context.rb +1 -0
- data/lib/makara/cookie.rb +1 -0
- data/lib/makara/error_handler.rb +0 -9
- data/lib/makara/errors/all_connections_blacklisted.rb +0 -2
- data/lib/makara/errors/blacklist_connection.rb +0 -2
- data/lib/makara/errors/blacklisted_while_in_transaction.rb +0 -2
- data/lib/makara/errors/invalid_shard.rb +1 -3
- data/lib/makara/errors/makara_error.rb +0 -1
- data/lib/makara/errors/no_connections_available.rb +0 -2
- data/lib/makara/logging/logger.rb +0 -4
- data/lib/makara/logging/subscriber.rb +0 -2
- data/lib/makara/middleware.rb +1 -2
- data/lib/makara/pool.rb +2 -7
- data/lib/makara/proxy.rb +25 -27
- data/lib/makara/railtie.rb +0 -2
- data/lib/makara/strategies/abstract.rb +1 -0
- data/lib/makara/strategies/priority_failover.rb +2 -0
- data/lib/makara/strategies/round_robin.rb +1 -3
- data/lib/makara/strategies/shard_aware.rb +0 -2
- data/lib/makara/version.rb +1 -3
- data/makara.gemspec +24 -5
- data/spec/active_record/connection_adapters/makara_abstract_adapter_error_handling_spec.rb +1 -6
- data/spec/active_record/connection_adapters/makara_abstract_adapter_spec.rb +0 -9
- data/spec/active_record/connection_adapters/makara_mysql2_adapter_spec.rb +9 -22
- data/spec/active_record/connection_adapters/makara_postgis_adapter_spec.rb +2 -10
- data/spec/active_record/connection_adapters/makara_postgresql_adapter_spec.rb +7 -20
- data/spec/cache_spec.rb +0 -1
- data/spec/config_parser_spec.rb +54 -56
- data/spec/connection_wrapper_spec.rb +1 -2
- data/spec/cookie_spec.rb +1 -1
- data/spec/middleware_spec.rb +1 -1
- data/spec/pool_spec.rb +3 -16
- data/spec/proxy_spec.rb +0 -4
- data/spec/spec_helper.rb +5 -1
- data/spec/strategies/priority_failover_spec.rb +3 -4
- data/spec/strategies/round_robin_spec.rb +4 -8
- data/spec/strategies/shard_aware_spec.rb +4 -5
- data/spec/support/deep_dup.rb +1 -1
- data/spec/support/helpers.rb +5 -5
- data/spec/support/mock_objects.rb +1 -4
- data/spec/support/mysql2_database.yml +2 -2
- data/spec/support/mysql2_database_with_custom_errors.yml +2 -2
- data/spec/support/pool_extensions.rb +0 -3
- data/spec/support/postgis_schema.rb +1 -1
- data/spec/support/postgresql_database.yml +0 -2
- data/spec/support/proxy_extensions.rb +1 -3
- data/spec/support/schema.rb +1 -1
- data/spec/support/user.rb +1 -2
- metadata +156 -20
- data/.travis.yml +0 -131
- data/gemfiles/ar-head.gemfile +0 -24
- data/gemfiles/ar30.gemfile +0 -36
- data/gemfiles/ar31.gemfile +0 -36
- data/gemfiles/ar32.gemfile +0 -36
- data/gemfiles/ar40.gemfile +0 -24
- data/gemfiles/ar41.gemfile +0 -24
- data/gemfiles/ar42.gemfile +0 -24
- data/gemfiles/ar50.gemfile +0 -24
- data/gemfiles/ar51.gemfile +0 -24
- data/gemfiles/ar52.gemfile +0 -24
- data/gemfiles/ar60.gemfile +0 -24
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Makara::ConnectionWrapper do
|
4
|
-
|
5
|
-
let(:proxy){ FakeProxy.new({:makara => {:blacklist_duration => 5, :connections => [{:role => 'master'}, {:role => 'slave'}, {:role => 'slave'}]}}) }
|
4
|
+
let(:proxy){ FakeProxy.new({makara: {blacklist_duration: 5, connections: [{role: 'master'}, {role: 'slave'}, {role: 'slave'}]}}) }
|
6
5
|
let(:connection){ subject._makara_connection }
|
7
6
|
|
8
7
|
subject{ proxy.master_pool.connections.first }
|
data/spec/cookie_spec.rb
CHANGED
@@ -63,7 +63,7 @@ describe Makara::Cookie do
|
|
63
63
|
end
|
64
64
|
|
65
65
|
it 'allows custom cookie options to be provided' do
|
66
|
-
Makara::Cookie.store(context_data, headers, { :
|
66
|
+
Makara::Cookie.store(context_data, headers, { secure: true })
|
67
67
|
|
68
68
|
expect(headers['Set-Cookie']).to include("#{cookie_key}=mysql%3A#{(now + 5).to_f}%7Credis%3A#{(now + 5).to_f};")
|
69
69
|
expect(headers['Set-Cookie']).to include("path=/; max-age=10; expires=#{(Time.now + 10).httpdate}; secure; HttpOnly")
|
data/spec/middleware_spec.rb
CHANGED
@@ -12,7 +12,7 @@ describe Makara::Middleware do
|
|
12
12
|
|
13
13
|
let(:env){ {} }
|
14
14
|
let(:proxy){ FakeProxy.new(config(1,2)) }
|
15
|
-
let(:middleware){ described_class.new(app, :
|
15
|
+
let(:middleware){ described_class.new(app, secure: true) }
|
16
16
|
|
17
17
|
let(:key){ Makara::Cookie::IDENTIFIER }
|
18
18
|
|
data/spec/pool_spec.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Makara::Pool do
|
4
|
-
|
5
|
-
let(:proxy){ FakeProxy.new({:makara => pool_config.merge(:connections => [])}) }
|
4
|
+
let(:proxy){ FakeProxy.new({makara: pool_config.merge(connections: [])}) }
|
6
5
|
let(:pool){ Makara::Pool.new('test', proxy) }
|
7
|
-
let(:pool_config){ {:
|
6
|
+
let(:pool_config){ {blacklist_duration: 5} }
|
8
7
|
let(:master_pool){ Makara::Pool.new('master', proxy) }
|
9
8
|
|
10
9
|
it 'should wrap connections with a ConnectionWrapper as theyre added to the pool' do
|
@@ -13,7 +12,7 @@ describe Makara::Pool do
|
|
13
12
|
connection_a = FakeConnection.new(something: 'a')
|
14
13
|
|
15
14
|
wrapper_a = pool.add(pool_config){ connection_a }
|
16
|
-
wrapper_b = pool.add(pool_config.merge(:
|
15
|
+
wrapper_b = pool.add(pool_config.merge(weight: 2)){ FakeConnection.new }
|
17
16
|
|
18
17
|
connections = pool.connections
|
19
18
|
weighted_connections = pool.strategy.instance_variable_get("@weighted_connections")
|
@@ -29,7 +28,6 @@ describe Makara::Pool do
|
|
29
28
|
end
|
30
29
|
|
31
30
|
it 'should determine if its completely blacklisted' do
|
32
|
-
|
33
31
|
pool.add(pool_config){ FakeConnection.new }
|
34
32
|
pool.add(pool_config){ FakeConnection.new }
|
35
33
|
|
@@ -41,7 +39,6 @@ describe Makara::Pool do
|
|
41
39
|
end
|
42
40
|
|
43
41
|
it 'sends methods to all underlying objects if asked to' do
|
44
|
-
|
45
42
|
a = FakeConnection.new
|
46
43
|
b = FakeConnection.new
|
47
44
|
|
@@ -52,11 +49,9 @@ describe Makara::Pool do
|
|
52
49
|
expect(b).to receive(:query).with('test').once
|
53
50
|
|
54
51
|
pool.send_to_all :query, 'test'
|
55
|
-
|
56
52
|
end
|
57
53
|
|
58
54
|
it 'only sends methods to underlying objects which are not blacklisted' do
|
59
|
-
|
60
55
|
a = FakeConnection.new
|
61
56
|
b = FakeConnection.new
|
62
57
|
c = FakeConnection.new
|
@@ -72,11 +67,9 @@ describe Makara::Pool do
|
|
72
67
|
wrapper_c._makara_blacklist!
|
73
68
|
|
74
69
|
pool.send_to_all :query, 'test'
|
75
|
-
|
76
70
|
end
|
77
71
|
|
78
72
|
it 'provides the next connection and blacklists' do
|
79
|
-
|
80
73
|
connection_a = FakeConnection.new(something: 'a')
|
81
74
|
connection_b = FakeConnection.new(something: 'b')
|
82
75
|
|
@@ -96,7 +89,6 @@ describe Makara::Pool do
|
|
96
89
|
expect(wrapper_a._makara_blacklisted?).to eq(false)
|
97
90
|
expect(wrapper_b._makara_blacklisted?).to eq(false)
|
98
91
|
end
|
99
|
-
|
100
92
|
end
|
101
93
|
|
102
94
|
it 'provides the same connection if the context has not changed and the proxy is sticky' do
|
@@ -126,7 +118,6 @@ describe Makara::Pool do
|
|
126
118
|
end
|
127
119
|
|
128
120
|
it 'raises an error when all connections are blacklisted' do
|
129
|
-
|
130
121
|
wrapper_a = pool.add(pool_config.dup){ FakeConnection.new }
|
131
122
|
wrapper_b = pool.add(pool_config.dup){ FakeConnection.new }
|
132
123
|
|
@@ -135,7 +126,6 @@ describe Makara::Pool do
|
|
135
126
|
|
136
127
|
allow(pool).to receive(:next).and_return(wrapper_a, wrapper_b, nil)
|
137
128
|
|
138
|
-
|
139
129
|
begin
|
140
130
|
pool.provide do |connection|
|
141
131
|
raise Makara::Errors::BlacklistConnection.new(connection, StandardError.new('failure'))
|
@@ -147,7 +137,6 @@ describe Makara::Pool do
|
|
147
137
|
end
|
148
138
|
|
149
139
|
it 'skips blacklisted connections when choosing the next one' do
|
150
|
-
|
151
140
|
pool.add(pool_config){ FakeConnection.new }
|
152
141
|
pool.add(pool_config){ FakeConnection.new }
|
153
142
|
|
@@ -155,7 +144,6 @@ describe Makara::Pool do
|
|
155
144
|
wrapper_b._makara_blacklist!
|
156
145
|
|
157
146
|
10.times{ pool.provide{|connection| expect(connection).not_to eq(wrapper_b) } }
|
158
|
-
|
159
147
|
end
|
160
148
|
|
161
149
|
it 'should error out while blacklisted in transaction' do
|
@@ -180,5 +168,4 @@ describe Makara::Pool do
|
|
180
168
|
end
|
181
169
|
10.times{ master_pool.provide{|connection| expect(connection).not_to eq(wrapper_a) } }
|
182
170
|
end
|
183
|
-
|
184
171
|
end
|
data/spec/proxy_spec.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Makara::Proxy do
|
4
|
-
|
5
4
|
let(:klass){ FakeProxy }
|
6
5
|
|
7
|
-
|
8
6
|
it 'sets up a master and slave pool no matter the number of connections' do
|
9
7
|
proxy = klass.new(config(0, 0))
|
10
8
|
expect(proxy.master_pool).to be_a(Makara::Pool)
|
@@ -23,7 +21,6 @@ describe Makara::Proxy do
|
|
23
21
|
expect(proxy.slave_pool).to be_a(Makara::Pool)
|
24
22
|
end
|
25
23
|
|
26
|
-
|
27
24
|
it 'instantiates N connections within each pool' do
|
28
25
|
proxy = klass.new(config(1, 2))
|
29
26
|
|
@@ -89,7 +86,6 @@ describe Makara::Proxy do
|
|
89
86
|
end
|
90
87
|
end
|
91
88
|
|
92
|
-
|
93
89
|
describe '#appropriate_pool' do
|
94
90
|
let(:proxy) { klass.new(config(1,1)) }
|
95
91
|
|
data/spec/spec_helper.rb
CHANGED
@@ -6,7 +6,7 @@ require 'yaml'
|
|
6
6
|
require 'rack'
|
7
7
|
|
8
8
|
begin
|
9
|
-
require '
|
9
|
+
require 'pry'
|
10
10
|
rescue LoadError
|
11
11
|
end
|
12
12
|
|
@@ -15,6 +15,10 @@ begin
|
|
15
15
|
rescue LoadError
|
16
16
|
end
|
17
17
|
|
18
|
+
if RUBY_VERSION >= "2.7.0"
|
19
|
+
Warning[:deprecated] = true
|
20
|
+
end
|
21
|
+
|
18
22
|
RSpec.configure do |config|
|
19
23
|
config.run_all_when_everything_filtered = true
|
20
24
|
config.filter_run :focus
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Makara::Strategies::PriorityFailover do
|
4
|
-
let(:proxy){ FakeProxy.new({:
|
4
|
+
let(:proxy){ FakeProxy.new({makara: pool_config.merge(makara_config).merge(connections: [])}) }
|
5
5
|
let(:pool){ Makara::Pool.new('master', proxy) }
|
6
|
-
let(:pool_config){ {:
|
7
|
-
let(:makara_config) { { :
|
6
|
+
let(:pool_config){ {blacklist_duration: 5} }
|
7
|
+
let(:makara_config) { { master_strategy: 'failover' } }
|
8
8
|
let(:strategy) { pool.strategy }
|
9
9
|
|
10
10
|
it 'should use the strategy' do
|
@@ -45,5 +45,4 @@ describe Makara::Strategies::PriorityFailover do
|
|
45
45
|
expect(strategy.current.something).to eql('b')
|
46
46
|
expect(strategy.next.something).to eql('b')
|
47
47
|
end
|
48
|
-
|
49
48
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Makara::Strategies::RoundRobin do
|
4
|
-
let(:proxy){ FakeProxy.new({:
|
4
|
+
let(:proxy){ FakeProxy.new({makara: pool_config.merge(makara_config).merge(connections: [])}) }
|
5
5
|
let(:pool){ Makara::Pool.new('test', proxy) }
|
6
|
-
let(:pool_config){ {:
|
6
|
+
let(:pool_config){ {blacklist_duration: 5} }
|
7
7
|
let(:makara_config) { {} }
|
8
8
|
let(:strategy) { pool.strategy }
|
9
9
|
|
@@ -14,7 +14,7 @@ describe Makara::Strategies::RoundRobin do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
context 'bad config' do
|
17
|
-
let(:makara_config) { { :
|
17
|
+
let(:makara_config) { { test_strategy: 'SomethingElse::Here' } }
|
18
18
|
it 'should raise name error' do
|
19
19
|
expect {
|
20
20
|
pool
|
@@ -23,13 +23,12 @@ describe Makara::Strategies::RoundRobin do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
context 'given in config' do
|
26
|
-
let(:makara_config) { { :
|
26
|
+
let(:makara_config) { { test_strategy: 'round_robin' } }
|
27
27
|
it 'should use the strategy' do
|
28
28
|
expect(pool.strategy).to be_instance_of(Makara::Strategies::RoundRobin)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
32
|
it 'should loop through with weights' do
|
34
33
|
wrapper_a = pool.add(pool_config){ FakeConnection.new(something: 'a') }
|
35
34
|
wrapper_b = pool.add(pool_config){ FakeConnection.new(something: 'b') }
|
@@ -61,7 +60,4 @@ describe Makara::Strategies::RoundRobin do
|
|
61
60
|
expect(strategy.next.something).to eql('c')
|
62
61
|
expect(strategy.next.something).to eql('b')
|
63
62
|
end
|
64
|
-
|
65
|
-
|
66
|
-
|
67
63
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Makara::Strategies::ShardAware do
|
4
|
-
|
5
4
|
def with_shard(shard_id)
|
6
5
|
begin
|
7
6
|
Thread.current['makara_shard_id'] = shard_id
|
@@ -12,7 +11,7 @@ describe Makara::Strategies::ShardAware do
|
|
12
11
|
end
|
13
12
|
|
14
13
|
describe "failover strategy with shard awareness," do
|
15
|
-
let(:proxy){ FakeProxy.new({:
|
14
|
+
let(:proxy){ FakeProxy.new({makara: pool_config.merge(makara_config).merge(connections: [])}) }
|
16
15
|
let(:pool){ Makara::Pool.new('master', proxy) }
|
17
16
|
let(:pool_config){ { blacklist_duration: 5} }
|
18
17
|
let(:makara_config) { {
|
@@ -109,7 +108,7 @@ describe Makara::Strategies::ShardAware do
|
|
109
108
|
end
|
110
109
|
|
111
110
|
describe "round_robin strategy with shard awareness," do
|
112
|
-
let(:proxy){ FakeProxy.new({:
|
111
|
+
let(:proxy){ FakeProxy.new({makara: pool_config.merge(makara_config).merge(connections: [])}) }
|
113
112
|
let(:pool){ Makara::Pool.new('master', proxy) }
|
114
113
|
let(:pool_config){ { blacklist_duration: 5} }
|
115
114
|
let(:makara_config) { {
|
@@ -186,7 +185,7 @@ describe Makara::Strategies::ShardAware do
|
|
186
185
|
end
|
187
186
|
|
188
187
|
describe "uses the configured failover strategy when shard_aware set to false," do
|
189
|
-
let(:proxy){ FakeProxy.new({:
|
188
|
+
let(:proxy){ FakeProxy.new({makara: pool_config.merge(makara_config).merge(connections: [])}) }
|
190
189
|
let(:pool){ Makara::Pool.new('master', proxy) }
|
191
190
|
let(:pool_config){ { blacklist_duration: 5} }
|
192
191
|
let(:makara_config) { {
|
@@ -202,7 +201,7 @@ describe Makara::Strategies::ShardAware do
|
|
202
201
|
end
|
203
202
|
|
204
203
|
describe "uses the configured roundrobin strategy when shard_aware set to false," do
|
205
|
-
let(:proxy){ FakeProxy.new({:
|
204
|
+
let(:proxy){ FakeProxy.new({makara: pool_config.merge(makara_config).merge(connections: [])}) }
|
206
205
|
let(:pool){ Makara::Pool.new('master', proxy) }
|
207
206
|
let(:pool_config){ { blacklist_duration: 5} }
|
208
207
|
let(:makara_config) { {
|
data/spec/support/deep_dup.rb
CHANGED
data/spec/support/helpers.rb
CHANGED
@@ -11,16 +11,16 @@ module SpecHelpers
|
|
11
11
|
|
12
12
|
def config(masters = 1, slaves = 2)
|
13
13
|
connections = []
|
14
|
-
masters.times{ connections << {:
|
15
|
-
slaves.times{ connections << {:
|
14
|
+
masters.times{ connections << {role: 'master'} }
|
15
|
+
slaves.times{ connections << {role: 'slave'} }
|
16
16
|
{
|
17
|
-
:
|
17
|
+
makara: {
|
18
18
|
# Defaults:
|
19
19
|
# :master_ttl => 5,
|
20
20
|
# :blacklist_duration => 30,
|
21
21
|
# :sticky => true
|
22
|
-
:
|
23
|
-
:
|
22
|
+
id: 'mock_mysql',
|
23
|
+
connections: connections
|
24
24
|
}
|
25
25
|
}
|
26
26
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'active_record/connection_adapters/makara_abstract_adapter'
|
2
2
|
|
3
3
|
class FakeConnection < Struct.new(:config)
|
4
|
-
|
5
4
|
def ping
|
6
5
|
'ping!'
|
7
6
|
end
|
@@ -32,7 +31,6 @@ class FakeConnection < Struct.new(:config)
|
|
32
31
|
end
|
33
32
|
|
34
33
|
class FakeDatabaseAdapter < Struct.new(:config)
|
35
|
-
|
36
34
|
def execute(sql, name = nil)
|
37
35
|
[]
|
38
36
|
end
|
@@ -48,11 +46,9 @@ class FakeDatabaseAdapter < Struct.new(:config)
|
|
48
46
|
def active?
|
49
47
|
true
|
50
48
|
end
|
51
|
-
|
52
49
|
end
|
53
50
|
|
54
51
|
class FakeProxy < Makara::Proxy
|
55
|
-
|
56
52
|
send_to_all :ping
|
57
53
|
hijack_method :execute
|
58
54
|
|
@@ -62,6 +58,7 @@ class FakeProxy < Makara::Proxy
|
|
62
58
|
|
63
59
|
def needs_master?(method_name, args)
|
64
60
|
return false if args.first =~ /^select/
|
61
|
+
|
65
62
|
true
|
66
63
|
end
|
67
64
|
end
|
@@ -5,7 +5,7 @@ conn.execute "create extension if not exists postgis"
|
|
5
5
|
if conn.table_exists? "towns"
|
6
6
|
conn.execute("TRUNCATE TABLE towns")
|
7
7
|
else
|
8
|
-
conn.create_table "towns", :
|
8
|
+
conn.create_table "towns", force: true do |t|
|
9
9
|
t.st_point "location"
|
10
10
|
end
|
11
11
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module ProxyExtensions
|
2
|
-
|
3
2
|
attr_reader :master_pool, :slave_pool, :id
|
4
|
-
|
3
|
+
|
5
4
|
def master_for?(sql)
|
6
5
|
pool_for(sql) == master_pool
|
7
6
|
end
|
@@ -27,7 +26,6 @@ module ProxyExtensions
|
|
27
26
|
def sticky=(s)
|
28
27
|
@sticky = s
|
29
28
|
end
|
30
|
-
|
31
29
|
end
|
32
30
|
|
33
31
|
Makara::Proxy.send(:include, ProxyExtensions)
|
data/spec/support/schema.rb
CHANGED
data/spec/support/user.rb
CHANGED