makara 0.4.1 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. checksums.yaml +5 -5
  2. data/.github/dependabot.yml +11 -0
  3. data/.github/workflows/CI.yml +88 -0
  4. data/.github/workflows/gem-publish-public.yml +36 -0
  5. data/.rspec +1 -1
  6. data/.rubocop.yml +15 -0
  7. data/.rubocop_todo.yml +670 -0
  8. data/CHANGELOG.md +69 -48
  9. data/Gemfile +1 -16
  10. data/README.md +8 -9
  11. data/Rakefile +1 -1
  12. data/gemfiles/activerecord_5.2.gemfile +8 -0
  13. data/gemfiles/activerecord_6.0.gemfile +8 -0
  14. data/gemfiles/activerecord_6.1.gemfile +8 -0
  15. data/gemfiles/activerecord_head.gemfile +6 -0
  16. data/lib/active_record/connection_adapters/jdbcmysql_makara_adapter.rb +4 -18
  17. data/lib/active_record/connection_adapters/jdbcpostgresql_makara_adapter.rb +4 -18
  18. data/lib/active_record/connection_adapters/makara_abstract_adapter.rb +107 -30
  19. data/lib/active_record/connection_adapters/makara_jdbcmysql_adapter.rb +4 -18
  20. data/lib/active_record/connection_adapters/makara_jdbcpostgresql_adapter.rb +4 -18
  21. data/lib/active_record/connection_adapters/makara_mysql2_adapter.rb +4 -20
  22. data/lib/active_record/connection_adapters/makara_postgis_adapter.rb +4 -19
  23. data/lib/active_record/connection_adapters/makara_postgresql_adapter.rb +4 -20
  24. data/lib/active_record/connection_adapters/mysql2_makara_adapter.rb +4 -20
  25. data/lib/active_record/connection_adapters/postgresql_makara_adapter.rb +4 -20
  26. data/lib/makara/cache.rb +0 -2
  27. data/lib/makara/config_parser.rb +7 -15
  28. data/lib/makara/connection_wrapper.rb +43 -22
  29. data/lib/makara/context.rb +1 -0
  30. data/lib/makara/cookie.rb +1 -0
  31. data/lib/makara/error_handler.rb +0 -9
  32. data/lib/makara/errors/all_connections_blacklisted.rb +0 -2
  33. data/lib/makara/errors/blacklist_connection.rb +0 -2
  34. data/lib/makara/errors/blacklisted_while_in_transaction.rb +12 -0
  35. data/lib/makara/errors/invalid_shard.rb +14 -0
  36. data/lib/makara/errors/makara_error.rb +0 -1
  37. data/lib/makara/errors/no_connections_available.rb +0 -2
  38. data/lib/makara/logging/logger.rb +0 -4
  39. data/lib/makara/logging/subscriber.rb +0 -2
  40. data/lib/makara/middleware.rb +1 -2
  41. data/lib/makara/pool.rb +49 -31
  42. data/lib/makara/proxy.rb +56 -30
  43. data/lib/makara/railtie.rb +0 -2
  44. data/lib/makara/strategies/abstract.rb +1 -0
  45. data/lib/makara/strategies/priority_failover.rb +2 -0
  46. data/lib/makara/strategies/round_robin.rb +1 -3
  47. data/lib/makara/strategies/shard_aware.rb +45 -0
  48. data/lib/makara/version.rb +1 -3
  49. data/lib/makara.rb +7 -6
  50. data/makara.gemspec +26 -3
  51. data/spec/active_record/connection_adapters/makara_abstract_adapter_error_handling_spec.rb +1 -6
  52. data/spec/active_record/connection_adapters/makara_abstract_adapter_spec.rb +0 -9
  53. data/spec/active_record/connection_adapters/makara_mysql2_adapter_spec.rb +9 -22
  54. data/spec/active_record/connection_adapters/makara_postgis_adapter_spec.rb +2 -10
  55. data/spec/active_record/connection_adapters/makara_postgresql_adapter_spec.rb +62 -18
  56. data/spec/cache_spec.rb +0 -1
  57. data/spec/config_parser_spec.rb +54 -56
  58. data/spec/connection_wrapper_spec.rb +1 -2
  59. data/spec/cookie_spec.rb +4 -4
  60. data/spec/middleware_spec.rb +2 -2
  61. data/spec/pool_spec.rb +25 -14
  62. data/spec/proxy_spec.rb +0 -4
  63. data/spec/spec_helper.rb +6 -1
  64. data/spec/strategies/priority_failover_spec.rb +3 -4
  65. data/spec/strategies/round_robin_spec.rb +4 -8
  66. data/spec/strategies/shard_aware_spec.rb +218 -0
  67. data/spec/support/deep_dup.rb +1 -1
  68. data/spec/support/helpers.rb +5 -5
  69. data/spec/support/mock_objects.rb +5 -4
  70. data/spec/support/mysql2_database.yml +2 -2
  71. data/spec/support/mysql2_database_with_custom_errors.yml +2 -2
  72. data/spec/support/pool_extensions.rb +0 -3
  73. data/spec/support/postgis_schema.rb +1 -1
  74. data/spec/support/postgresql_database.yml +0 -2
  75. data/spec/support/proxy_extensions.rb +1 -3
  76. data/spec/support/schema.rb +1 -1
  77. data/spec/support/user.rb +1 -2
  78. metadata +165 -20
  79. data/.travis.yml +0 -105
  80. data/gemfiles/ar-head.gemfile +0 -24
  81. data/gemfiles/ar30.gemfile +0 -36
  82. data/gemfiles/ar31.gemfile +0 -36
  83. data/gemfiles/ar32.gemfile +0 -36
  84. data/gemfiles/ar40.gemfile +0 -24
  85. data/gemfiles/ar41.gemfile +0 -24
  86. data/gemfiles/ar42.gemfile +0 -24
  87. data/gemfiles/ar50.gemfile +0 -24
  88. data/gemfiles/ar51.gemfile +0 -24
@@ -1,6 +1,5 @@
1
1
  module Makara
2
2
  module Logging
3
-
4
3
  module Subscriber
5
4
  IGNORE_PAYLOAD_NAMES = ["SCHEMA", "EXPLAIN"]
6
5
 
@@ -33,6 +32,5 @@ module Makara
33
32
  "[#{adapter._makara_name}]"
34
33
  end
35
34
  end
36
-
37
35
  end
38
36
  end
@@ -3,7 +3,6 @@ require 'rack'
3
3
  # Persists the Makara::Context across requests ensuring the same master pool is used on subsequent requests.
4
4
  module Makara
5
5
  class Middleware
6
-
7
6
  def initialize(app, cookie_options = {})
8
7
  @app = app
9
8
  @cookie_options = cookie_options
@@ -11,6 +10,7 @@ module Makara
11
10
 
12
11
  def call(env)
13
12
  return @app.call(env) if ignore_request?(env)
13
+
14
14
  set_current_context(env)
15
15
 
16
16
  status, headers, body = @app.call(env)
@@ -19,7 +19,6 @@ module Makara
19
19
  [status, headers, body]
20
20
  end
21
21
 
22
-
23
22
  protected
24
23
 
25
24
  def set_current_context(env)
data/lib/makara/pool.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  require 'active_support/core_ext/hash/keys'
2
+ require 'makara/strategies/shard_aware'
2
3
 
3
4
  # Wraps a collection of similar connections and chooses which one to use
4
5
  # Provides convenience methods for accessing underlying connections
5
6
 
6
7
  module Makara
7
8
  class Pool
8
-
9
9
  # there are cases when we understand the pool is busted and we essentially want to skip
10
10
  # all execution
11
11
  attr_accessor :disabled
@@ -13,6 +13,8 @@ module Makara
13
13
  attr_reader :role
14
14
  attr_reader :connections
15
15
  attr_reader :strategy
16
+ attr_reader :shard_strategy_class
17
+ attr_reader :default_shard
16
18
 
17
19
  def initialize(role, proxy)
18
20
  @role = role
@@ -20,10 +22,15 @@ module Makara
20
22
  @connections = []
21
23
  @blacklist_errors = []
22
24
  @disabled = false
23
- @strategy = proxy.strategy_for(role)
25
+ if proxy.shard_aware_for(role)
26
+ @strategy = Makara::Strategies::ShardAware.new(self)
27
+ @shard_strategy_class = proxy.strategy_class_for(proxy.strategy_name_for(role))
28
+ @default_shard = proxy.default_shard_for(role)
29
+ else
30
+ @strategy = proxy.strategy_for(role)
31
+ end
24
32
  end
25
33
 
26
-
27
34
  def completely_blacklisted?
28
35
  @connections.each do |connection|
29
36
  return false unless connection._makara_blacklisted?
@@ -31,7 +38,6 @@ module Makara
31
38
  true
32
39
  end
33
40
 
34
-
35
41
  # Add a connection to this pool, wrapping the connection with a Makara::ConnectionWrapper
36
42
  def add(config)
37
43
  config[:name] ||= "#{@role}/#{@connections.length + 1}"
@@ -61,6 +67,7 @@ module Makara
61
67
 
62
68
  @connections.each do |con|
63
69
  next if con._makara_blacklisted?
70
+
64
71
  begin
65
72
  ret = @proxy.error_handler.handle(con) do
66
73
  if block
@@ -91,52 +98,63 @@ module Makara
91
98
  # Provide a connection that is not blacklisted and connected. Handle any errors
92
99
  # that may occur within the block.
93
100
  def provide
94
- provided_connection = self.next
101
+ attempt = 0
102
+ begin
103
+ provided_connection = self.next
95
104
 
96
- # nil implies that it's blacklisted
97
- if provided_connection
105
+ # nil implies that it's blacklisted
106
+ if provided_connection
98
107
 
99
- value = @proxy.error_handler.handle(provided_connection) do
100
- yield provided_connection
101
- end
108
+ value = @proxy.error_handler.handle(provided_connection) do
109
+ yield provided_connection
110
+ end
102
111
 
103
- @blacklist_errors = []
112
+ @blacklist_errors = []
104
113
 
105
- value
114
+ value
106
115
 
107
- # if we've made any connections within this pool, we should report the blackout.
108
- elsif connection_made?
109
- err = Makara::Errors::AllConnectionsBlacklisted.new(self, @blacklist_errors)
110
- @blacklist_errors = []
111
- raise err
112
- else
113
- raise Makara::Errors::NoConnectionsAvailable.new(@role) unless @disabled
114
- end
116
+ # if we've made any connections within this pool, we should report the blackout.
117
+ elsif connection_made?
118
+ err = Makara::Errors::AllConnectionsBlacklisted.new(self, @blacklist_errors)
119
+ @blacklist_errors = []
120
+ raise err
121
+ else
122
+ raise Makara::Errors::NoConnectionsAvailable.new(@role) unless @disabled
123
+ end
115
124
 
116
- # when a connection causes a blacklist error within the provided block, we blacklist it then retry
117
- rescue Makara::Errors::BlacklistConnection => e
118
- @blacklist_errors.insert(0, e)
119
- provided_connection._makara_blacklist!
120
- retry
125
+ # when a connection causes a blacklist error within the provided block, we blacklist it then retry
126
+ rescue Makara::Errors::BlacklistConnection => e
127
+ @blacklist_errors.insert(0, e)
128
+ in_transaction = self.role == "master" && provided_connection._makara_in_transaction?
129
+ provided_connection._makara_blacklist!
130
+ raise Makara::Errors::BlacklistedWhileInTransaction.new(@role) if in_transaction
131
+
132
+ attempt += 1
133
+ if attempt < @connections.length
134
+ retry
135
+ elsif connection_made?
136
+ err = Makara::Errors::AllConnectionsBlacklisted.new(self, @blacklist_errors)
137
+ @blacklist_errors = []
138
+ raise err
139
+ else
140
+ raise Makara::Errors::NoConnectionsAvailable.new(@role) unless @disabled
141
+ end
142
+ end
121
143
  end
122
144
 
123
-
124
-
125
145
  protected
126
146
 
127
-
128
147
  # have we connected to any of the underlying connections.
129
148
  def connection_made?
130
149
  @connections.any?(&:_makara_connected?)
131
150
  end
132
151
 
133
-
134
152
  # Get the next non-blacklisted connection. If the proxy is setup
135
153
  # to be sticky, provide back the current connection assuming it is
136
154
  # not blacklisted.
137
155
  def next
138
- if @proxy.sticky && @strategy.current
139
- @strategy.current
156
+ if @proxy.sticky && (curr = @strategy.current)
157
+ curr
140
158
  else
141
159
  @strategy.next
142
160
  end
data/lib/makara/proxy.rb CHANGED
@@ -11,11 +11,11 @@ require 'active_support/core_ext/string/inflections'
11
11
 
12
12
  module Makara
13
13
  class Proxy < ::SimpleDelegator
14
-
15
14
  METHOD_MISSING_SKIP = [ :byebug, :puts ]
16
15
 
17
- class_attribute :hijack_methods
16
+ class_attribute :hijack_methods, :control_methods
18
17
  self.hijack_methods = []
18
+ self.control_methods = []
19
19
 
20
20
  class << self
21
21
  def hijack_method(*method_names)
@@ -23,27 +23,44 @@ module Makara
23
23
  self.hijack_methods |= method_names
24
24
 
25
25
  method_names.each do |method_name|
26
- define_method method_name do |*args, &block|
26
+ define_method(method_name) do |*args, &block|
27
27
  appropriate_connection(method_name, args) do |con|
28
28
  con.send(method_name, *args, &block)
29
29
  end
30
30
  end
31
+
32
+ ruby2_keywords method_name if Module.private_method_defined?(:ruby2_keywords)
31
33
  end
32
34
  end
33
35
 
34
36
  def send_to_all(*method_names)
35
37
  method_names.each do |method_name|
36
- define_method method_name do |*args|
37
- send_to_all method_name, *args
38
+ define_method(method_name) do |*args|
39
+ send_to_all(method_name, *args)
38
40
  end
41
+
42
+ ruby2_keywords method_name if Module.private_method_defined?(:ruby2_keywords)
39
43
  end
40
44
  end
41
- end
42
45
 
46
+ def control_method(*method_names)
47
+ self.control_methods = self.control_methods || []
48
+ self.control_methods |= method_names
49
+
50
+ method_names.each do |method_name|
51
+ define_method(method_name) do |*args, &block|
52
+ control&.send(method_name, *args, &block)
53
+ end
54
+
55
+ ruby2_keywords method_name if Module.private_method_defined?(:ruby2_keywords)
56
+ end
57
+ end
58
+ end
43
59
 
44
60
  attr_reader :error_handler
45
61
  attr_reader :sticky
46
62
  attr_reader :config_parser
63
+ attr_reader :control
47
64
 
48
65
  def initialize(config)
49
66
  @config = config.symbolize_keys
@@ -84,6 +101,14 @@ module Makara
84
101
  @config_parser.makara_config["#{role}_strategy".to_sym]
85
102
  end
86
103
 
104
+ def shard_aware_for(role)
105
+ @config_parser.makara_config["#{role}_shard_aware".to_sym]
106
+ end
107
+
108
+ def default_shard_for(role)
109
+ @config_parser.makara_config["#{role}_default_shard".to_sym]
110
+ end
111
+
87
112
  def strategy_class_for(strategy_name)
88
113
  case strategy_name
89
114
  when 'round_robin', 'roundrobin', nil, ''
@@ -97,27 +122,25 @@ module Makara
97
122
 
98
123
  def method_missing(m, *args, &block)
99
124
  if METHOD_MISSING_SKIP.include?(m)
100
- return super(m, *args, &block)
125
+ return super
101
126
  end
102
127
 
103
128
  any_connection do |con|
104
- if con.respond_to?(m)
105
- con.public_send(m, *args, &block)
106
- elsif con.respond_to?(m, true)
107
- con.__send__(m, *args, &block)
129
+ if con.respond_to?(m, true)
130
+ con.send(m, *args, &block)
108
131
  else
109
- super(m, *args, &block)
132
+ super
110
133
  end
111
134
  end
112
135
  end
113
136
 
114
- class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
115
- def respond_to#{RUBY_VERSION.to_s =~ /^1.8/ ? nil : '_missing'}?(m, include_private = false)
116
- any_connection do |con|
117
- con._makara_connection.respond_to?(m, true)
118
- end
137
+ ruby2_keywords :method_missing if Module.private_method_defined?(:ruby2_keywords)
138
+
139
+ def respond_to_missing?(m, include_private = false)
140
+ any_connection do |con|
141
+ con._makara_connection.respond_to?(m, true)
119
142
  end
120
- RUBY_EVAL
143
+ end
121
144
 
122
145
  def graceful_connection_for(config)
123
146
  fake_wrapper = Makara::ConnectionWrapper.new(self, nil, config)
@@ -138,18 +161,25 @@ module Makara
138
161
 
139
162
  protected
140
163
 
141
-
142
164
  def send_to_all(method_name, *args)
143
165
  # slave pool must run first to allow for slave-->master failover without running operations on master twice.
144
166
  handling_an_all_execution(method_name) do
145
- @slave_pool.send_to_all method_name, *args
146
- @master_pool.send_to_all method_name, *args
167
+ @slave_pool.send_to_all(method_name, *args)
168
+ @master_pool.send_to_all(method_name, *args)
147
169
  end
148
170
  end
149
171
 
172
+ ruby2_keywords :send_to_all if Module.private_method_defined?(:ruby2_keywords)
173
+
150
174
  def any_connection
151
- @master_pool.provide do |con|
152
- yield con
175
+ if @master_pool.disabled
176
+ @slave_pool.provide do |con|
177
+ yield con
178
+ end
179
+ else
180
+ @master_pool.provide do |con|
181
+ yield con
182
+ end
153
183
  end
154
184
  rescue ::Makara::Errors::AllConnectionsBlacklisted, ::Makara::Errors::NoConnectionsAvailable
155
185
  begin
@@ -175,14 +205,11 @@ module Makara
175
205
  end
176
206
  end
177
207
 
178
-
179
208
  # master or slave
180
209
  def appropriate_pool(method_name, args)
181
-
182
210
  # for testing purposes
183
211
  pool = _appropriate_pool(method_name, args)
184
212
  yield pool
185
-
186
213
  rescue ::Makara::Errors::AllConnectionsBlacklisted, ::Makara::Errors::NoConnectionsAvailable => e
187
214
  if pool == @master_pool
188
215
  @master_pool.connections.each(&:_makara_whitelist!)
@@ -241,7 +268,6 @@ module Makara
241
268
  @hijacked = false
242
269
  end
243
270
 
244
-
245
271
  def stuck_to_master?
246
272
  sticky? && Makara::Context.stuck?(@id)
247
273
  end
@@ -286,18 +312,18 @@ module Makara
286
312
  yield
287
313
  rescue ::Makara::Errors::NoConnectionsAvailable => e
288
314
  if e.role == 'master'
289
- Kernel.raise ::Makara::Errors::NoConnectionsAvailable.new('master and slave')
315
+ # this means slave connections are good.
316
+ return
290
317
  end
318
+
291
319
  @slave_pool.disabled = true
292
320
  yield
293
321
  ensure
294
322
  @slave_pool.disabled = false
295
323
  end
296
324
 
297
-
298
325
  def connection_for(config)
299
326
  Kernel.raise NotImplementedError
300
327
  end
301
-
302
328
  end
303
329
  end
@@ -1,9 +1,7 @@
1
1
  module Makara
2
2
  class Railtie < ::Rails::Railtie
3
-
4
3
  initializer "makara.configure_rails_initialization" do |app|
5
4
  app.middleware.use Makara::Middleware
6
5
  end
7
-
8
6
  end
9
7
  end
@@ -2,6 +2,7 @@ module Makara
2
2
  module Strategies
3
3
  class Abstract
4
4
  attr_reader :pool
5
+
5
6
  def initialize(pool)
6
7
  @pool = pool
7
8
  init
@@ -27,6 +27,7 @@ module Makara
27
27
  @weighted_connections.each_with_index do |con, index|
28
28
  check = safe_value(index)
29
29
  next unless check
30
+
30
31
  @current_idx = index
31
32
  return check
32
33
  end
@@ -41,6 +42,7 @@ module Makara
41
42
  con = @weighted_connections[idx]
42
43
  return nil unless con
43
44
  return nil if con._makara_blacklisted?
45
+
44
46
  con
45
47
  end
46
48
  end
@@ -26,8 +26,8 @@ module Makara
26
26
  return safe_value(0, true) if single_one?
27
27
 
28
28
  idx = @current_idx
29
- begin
30
29
 
30
+ begin
31
31
  idx = next_index(idx)
32
32
 
33
33
  # if we've looped all the way around, return our safe value
@@ -48,7 +48,6 @@ module Makara
48
48
  idx
49
49
  end
50
50
 
51
-
52
51
  # return the connection if it's not blacklisted
53
52
  # otherwise return nil
54
53
  # optionally, store the position and context we're returning
@@ -64,7 +63,6 @@ module Makara
64
63
  con
65
64
  end
66
65
 
67
-
68
66
  # stub in test mode to ensure consistency
69
67
  def should_shuffle?
70
68
  true
@@ -0,0 +1,45 @@
1
+ require 'makara/errors/invalid_shard'
2
+
3
+ module Makara
4
+ module Strategies
5
+ class ShardAware < ::Makara::Strategies::Abstract
6
+ def init
7
+ @shards = {}
8
+ @default_shard = pool.default_shard
9
+ end
10
+
11
+ def connection_added(wrapper)
12
+ id = wrapper._makara_shard_id
13
+ shard_strategy(id).connection_added(wrapper)
14
+ end
15
+
16
+ def shard_strategy(shard_id)
17
+ id = shard_id
18
+ shard_strategy = @shards[id]
19
+ unless shard_strategy
20
+ shard_strategy = pool.shard_strategy_class.new(pool)
21
+ @shards[id] = shard_strategy
22
+ end
23
+ shard_strategy
24
+ end
25
+
26
+ def current
27
+ id = shard_id
28
+ raise Makara::Errors::InvalidShard.new(pool.role, id) unless id && @shards[id]
29
+
30
+ @shards[id].current
31
+ end
32
+
33
+ def next
34
+ id = shard_id
35
+ raise Makara::Errors::InvalidShard.new(pool.role, id) unless id && @shards[id]
36
+
37
+ @shards[id].next
38
+ end
39
+
40
+ def shard_id
41
+ Thread.current['makara_shard_id'] || pool.default_shard
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,15 +1,13 @@
1
1
  module Makara
2
2
  module VERSION
3
-
4
3
  MAJOR = 0
5
- MINOR = 4
4
+ MINOR = 5
6
5
  PATCH = 1
7
6
  PRE = nil
8
7
 
9
8
  def self.to_s
10
9
  [MAJOR, MINOR, PATCH, PRE].compact.join('.')
11
10
  end
12
-
13
11
  end unless defined?(::Makara::VERSION)
14
12
  ::Makara::VERSION
15
13
  end
data/lib/makara.rb CHANGED
@@ -2,7 +2,6 @@ require 'active_support'
2
2
  require 'makara/version'
3
3
  require 'makara/railtie' if defined?(Rails)
4
4
  module Makara
5
-
6
5
  autoload :Cache, 'makara/cache'
7
6
  autoload :ConfigParser, 'makara/config_parser'
8
7
  autoload :ConnectionWrapper, 'makara/connection_wrapper'
@@ -14,10 +13,12 @@ module Makara
14
13
  autoload :Proxy, 'makara/proxy'
15
14
 
16
15
  module Errors
17
- autoload :MakaraError, 'makara/errors/makara_error'
18
- autoload :AllConnectionsBlacklisted, 'makara/errors/all_connections_blacklisted'
19
- autoload :BlacklistConnection, 'makara/errors/blacklist_connection'
20
- autoload :NoConnectionsAvailable, 'makara/errors/no_connections_available'
16
+ autoload :MakaraError, 'makara/errors/makara_error'
17
+ autoload :AllConnectionsBlacklisted, 'makara/errors/all_connections_blacklisted'
18
+ autoload :BlacklistConnection, 'makara/errors/blacklist_connection'
19
+ autoload :NoConnectionsAvailable, 'makara/errors/no_connections_available'
20
+ autoload :BlacklistedWhileInTransaction, 'makara/errors/blacklisted_while_in_transaction'
21
+ autoload :InvalidShard, 'makara/errors/invalid_shard'
21
22
  end
22
23
 
23
24
  module Logging
@@ -29,8 +30,8 @@ module Makara
29
30
  autoload :Abstract, 'makara/strategies/abstract'
30
31
  autoload :RoundRobin, 'makara/strategies/round_robin'
31
32
  autoload :PriorityFailover, 'makara/strategies/priority_failover'
33
+ autoload :ShardAware, 'makara/strategies/shard_aware'
32
34
  end
33
-
34
35
  end
35
36
 
36
37
  ActiveSupport.on_load(:active_record) do
data/makara.gemspec CHANGED
@@ -1,4 +1,3 @@
1
- # -*- encoding: utf-8 -*-
2
1
  require File.expand_path('../lib/makara/version', __FILE__)
3
2
 
4
3
  Gem::Specification.new do |gem|
@@ -6,7 +5,11 @@ Gem::Specification.new do |gem|
6
5
  gem.email = ["mike@mikeonrails.com"]
7
6
  gem.description = %q{Read-write split your DB yo}
8
7
  gem.summary = %q{Read-write split your DB yo}
9
- gem.homepage = ""
8
+ gem.homepage = "https://github.com/instacart/makara"
9
+ gem.licenses = ['MIT']
10
+ gem.metadata = {
11
+ "source_code_uri" => 'https://github.com/instacart/makara'
12
+ }
10
13
 
11
14
  gem.files = `git ls-files`.split($\)
12
15
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -15,5 +18,25 @@ Gem::Specification.new do |gem|
15
18
  gem.require_paths = ["lib"]
16
19
  gem.version = Makara::VERSION
17
20
 
18
- gem.add_dependency 'activerecord', '>= 3.0.0'
21
+ gem.required_ruby_version = ">= 2.5.0"
22
+
23
+ gem.add_dependency "activerecord", ">= 5.2.0"
24
+
25
+ gem.add_development_dependency "rack"
26
+ gem.add_development_dependency "rake", "~> 13.0"
27
+ gem.add_development_dependency "rspec", "~> 3.9"
28
+ gem.add_development_dependency "timecop"
29
+ gem.add_development_dependency "rubocop", "~> 1.9.1"
30
+
31
+ if RUBY_ENGINE == "jruby"
32
+ gem.add_development_dependency "activerecord-jdbcmysql-adapter"
33
+ gem.add_development_dependency "activerecord-jdbcpostgresql-adapter"
34
+ gem.add_development_dependency "ruby-debug"
35
+ else
36
+ gem.add_development_dependency "activerecord-postgis-adapter"
37
+ gem.add_development_dependency "pry-byebug"
38
+ gem.add_development_dependency "mysql2"
39
+ gem.add_development_dependency "pg"
40
+ gem.add_development_dependency "rgeo"
41
+ end
19
42
  end
@@ -2,7 +2,6 @@ require 'spec_helper'
2
2
  require 'active_record/connection_adapters/makara_abstract_adapter'
3
3
 
4
4
  describe ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter::ErrorHandler do
5
-
6
5
  let(:handler){ described_class.new }
7
6
  let(:proxy) { FakeAdapter.new(config(1,1)) }
8
7
  let(:connection){ proxy.master_pool.connections.first }
@@ -60,9 +59,8 @@ describe ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter::ErrorHandler d
60
59
  end
61
60
 
62
61
  describe 'custom errors' do
63
-
64
62
  let(:config_path) { File.join(File.expand_path('../../../', __FILE__), 'support', 'mysql2_database_with_custom_errors.yml') }
65
- let(:config) { YAML.load_file(config_path)['test'] }
63
+ let(:config) { YAML.load(ERB.new(File.read(config_path)).result)['test'] }
66
64
  let(:handler){ described_class.new }
67
65
  let(:proxy) { FakeAdapter.new(config) }
68
66
  let(:connection){ proxy.master_pool.connections.first }
@@ -85,8 +83,5 @@ describe ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter::ErrorHandler d
85
83
  end
86
84
  }.to raise_error(Makara::Errors::BlacklistConnection)
87
85
  end
88
-
89
86
  end
90
-
91
-
92
87
  end
@@ -2,7 +2,6 @@ require 'spec_helper'
2
2
  require 'active_record/connection_adapters/makara_abstract_adapter'
3
3
 
4
4
  describe ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter do
5
-
6
5
  let(:klass){ FakeAdapter }
7
6
 
8
7
  {
@@ -38,15 +37,12 @@ describe ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter do
38
37
  'select pg_advisory_lock(12345)' => true,
39
38
  'select pg_advisory_unlock(12345)' => true
40
39
  }.each do |sql, should_go_to_master|
41
-
42
40
  it "determines that \"#{sql}\" #{should_go_to_master ? 'requires' : 'does not require'} master" do
43
41
  proxy = klass.new(config(1,1))
44
42
  expect(proxy.master_for?(sql)).to eq(should_go_to_master)
45
43
  end
46
-
47
44
  end
48
45
 
49
-
50
46
  {
51
47
  "SET @@things" => true,
52
48
  "INSERT INTO wisdom ('The truth will set you free.')" => false,
@@ -61,7 +57,6 @@ describe ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter do
61
57
  max_treats IS NULL
62
58
  } => false
63
59
  }.each do |sql, should_send_to_all_connections|
64
-
65
60
  it "determines that \"#{sql}\" #{should_send_to_all_connections ? 'should' : 'should not'} be sent to all underlying connections" do
66
61
  proxy = klass.new(config(1,1))
67
62
  proxy.master_pool.connections.each{|con| expect(con).to receive(:execute).with(sql).once}
@@ -75,7 +70,6 @@ describe ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter do
75
70
 
76
71
  proxy.execute(sql)
77
72
  end
78
-
79
73
  end
80
74
 
81
75
  {
@@ -108,12 +102,9 @@ describe ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter do
108
102
  max_treats IS NULL
109
103
  } => true
110
104
  }.each do |sql,should_stick|
111
-
112
105
  it "should #{should_stick ? 'stick' : 'not stick'} to master if handling sql like \"#{sql}\"" do
113
106
  proxy = klass.new(config(0,0))
114
107
  expect(proxy.would_stick?(sql)).to eq(should_stick)
115
108
  end
116
-
117
109
  end
118
-
119
110
  end