active_record_host_pool 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7baaf5e8c49a8308e3be6a9f52b41af880f0d8182a98a12be2ce8fa6d7ccbe60
4
- data.tar.gz: aa68d84f75c00f608d13d475761f936722171f3d3d59a4ede471513279e8cda2
3
+ metadata.gz: f5dcc0c95ead619555c18514507bf2711f7790c7e120570a5daaadf6506f1250
4
+ data.tar.gz: 37d82a6b2c495872cfa5522bd588c7dd047afa5b9cdc376acd9a9c96aba21d44
5
5
  SHA512:
6
- metadata.gz: 072b56581266326d5decfd1221ccb9bf2ffde945cd04e1ce52278dd89d3b9e84b4d59d0a8d8e21808352d25a0f360ed67a006f71dc112751b7937a42f21aa455
7
- data.tar.gz: c6075399e78ec309aeca872079044b042a5208dc1071c068eac01928a83b588d23cfc0d268907c0a9aa5c13a7d9b99005443e644b8142cb7ad9cb8a0e7cf013a
6
+ metadata.gz: dd36a23cbb9636ba2dda0f303776715e05aef42ddecafa583388b32c7c11adcae6a0285743eede486712559d20309fa5fe834bd44a9bc539c2cc985c3f80c344
7
+ data.tar.gz: d18bec930c1c6358d310461bd958fa3d92baee83e7de0d629783610809aea7f552ef98a1cc7482707cd8eaef4d592321a00f2210302132c31fead5d27b471962
@@ -32,7 +32,8 @@ module ActiveRecordHostPool
32
32
  super
33
33
  end
34
34
 
35
- def execute_with_switching(*args)
35
+ def self.ruby2_keywords(*); end unless respond_to?(:ruby2_keywords, true)
36
+ ruby2_keywords def execute_with_switching(*args)
36
37
  if _host_pool_current_database && !_no_switch
37
38
  _switch_connection
38
39
  end
@@ -97,7 +98,7 @@ module ActiveRecord
97
98
  module ConnectionAdapters
98
99
  class ConnectionHandler
99
100
  case "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
100
- when '6.1'
101
+ when '6.1', '7.0'
101
102
 
102
103
  :noop
103
104
 
@@ -122,6 +123,7 @@ ActiveRecord::ConnectionAdapters::Mysql2Adapter.include(ActiveRecordHostPool::Da
122
123
 
123
124
  # In Rails 6.1 Connection Pools are no longer instantiated in #establish_connection but in a
124
125
  # new pool method.
125
- if "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}" == '6.1'
126
+ case "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
127
+ when '6.1', '7.0'
126
128
  ActiveRecord::ConnectionAdapters::PoolConfig.prepend(ActiveRecordHostPool::PoolConfigPatch)
127
129
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}" == '6.1'
3
+ case "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
4
+ when '6.1', '7.0'
4
5
  require 'active_record_host_pool/pool_proxy_6_1'
5
6
  else
6
7
  require 'active_record_host_pool/pool_proxy_legacy'
@@ -0,0 +1,150 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'delegate'
4
+ require 'active_record'
5
+ require 'active_record_host_pool/connection_adapter_mixin'
6
+
7
+ # this module sits in between ConnectionHandler and a bunch of different ConnectionPools (one per host).
8
+ # when a connection is requested, it goes like:
9
+ # ActiveRecordClass -> ConnectionHandler#connection
10
+ # ConnectionHandler#connection -> (find or create PoolProxy)
11
+ # PoolProxy -> shared list of Pools
12
+ # Pool actually gives back a connection, then PoolProxy turns this
13
+ # into a ConnectionProxy that can inform (on execute) which db we should be on.
14
+
15
+ module ActiveRecordHostPool
16
+ # Sits between ConnectionHandler and a bunch of different ConnectionPools (one per host).
17
+ class PoolProxy < Delegator
18
+ def initialize(pool_config)
19
+ super(pool_config)
20
+ @pool_config = pool_config
21
+ @config = pool_config.db_config.configuration_hash
22
+ end
23
+
24
+ def __getobj__
25
+ _connection_pool
26
+ end
27
+
28
+ def __setobj__(pool_config)
29
+ @pool_config = pool_config
30
+ @config = pool_config.db_config.configuration_hash
31
+ @_pool_key = nil
32
+ end
33
+
34
+ attr_reader :pool_config
35
+
36
+ def connection(*args)
37
+ real_connection = _connection_pool.connection(*args)
38
+ _connection_proxy_for(real_connection, @config[:database])
39
+ rescue Mysql2::Error, ActiveRecord::NoDatabaseError
40
+ _connection_pools.delete(_pool_key)
41
+ Kernel.raise
42
+ end
43
+
44
+ # by the time we are patched into ActiveRecord, the current thread has already established
45
+ # a connection. thus we need to patch both connection and checkout/checkin
46
+ def checkout(*args, &block)
47
+ cx = _connection_pool.checkout(*args, &block)
48
+ _connection_proxy_for(cx, @config[:database])
49
+ end
50
+
51
+ def checkin(cx)
52
+ cx = cx.unproxied
53
+ _connection_pool.checkin(cx)
54
+ end
55
+
56
+ def with_connection
57
+ cx = checkout
58
+ yield cx
59
+ ensure
60
+ checkin cx
61
+ end
62
+
63
+ def disconnect!
64
+ p = _connection_pool(false)
65
+ return unless p
66
+
67
+ p.disconnect!
68
+ p.automatic_reconnect = true if p.respond_to?(:automatic_reconnect=)
69
+ _clear_connection_proxy_cache
70
+ end
71
+
72
+ def automatic_reconnect=(value)
73
+ p = _connection_pool(false)
74
+ return unless p
75
+
76
+ p.automatic_reconnect = value if p.respond_to?(:automatic_reconnect=)
77
+ end
78
+
79
+ def clear_reloadable_connections!
80
+ _connection_pool.clear_reloadable_connections!
81
+ _clear_connection_proxy_cache
82
+ end
83
+
84
+ def release_connection(*args)
85
+ p = _connection_pool(false)
86
+ return unless p
87
+
88
+ p.release_connection(*args)
89
+ end
90
+
91
+ def flush!
92
+ p = _connection_pool(false)
93
+ return unless p
94
+
95
+ p.flush!
96
+ end
97
+
98
+ def discard!
99
+ p = _connection_pool(false)
100
+ return unless p
101
+
102
+ p.discard!
103
+
104
+ # All connections in the pool (even if they're currently
105
+ # leased!) have just been discarded, along with the pool itself.
106
+ # Any further interaction with the pool (except #pool_config and #schema_cache)
107
+ # is undefined.
108
+ # Remove the connection for the given key so a new one can be created in its place
109
+ _connection_pools.delete(_pool_key)
110
+ end
111
+
112
+ private
113
+
114
+ def _connection_pools
115
+ @@_connection_pools ||= {}
116
+ end
117
+
118
+ def _pool_key
119
+ @_pool_key ||= "#{@config[:host]}/#{@config[:port]}/#{@config[:socket]}/" \
120
+ "#{@config[:username]}/#{replica_configuration? && 'replica'}"
121
+ end
122
+
123
+ def _connection_pool(auto_create = true)
124
+ pool = _connection_pools[_pool_key]
125
+ if pool.nil? && auto_create
126
+ pool = _connection_pools[_pool_key] = ActiveRecord::ConnectionAdapters::ConnectionPool.new(@pool_config)
127
+ end
128
+ pool
129
+ end
130
+
131
+ def _connection_proxy_for(connection, database)
132
+ @connection_proxy_cache ||= {}
133
+ key = [connection, database]
134
+
135
+ @connection_proxy_cache[key] ||= begin
136
+ cx = ActiveRecordHostPool::ConnectionProxy.new(connection, database)
137
+ cx.execute('select 1')
138
+ cx
139
+ end
140
+ end
141
+
142
+ def _clear_connection_proxy_cache
143
+ @connection_proxy_cache = {}
144
+ end
145
+
146
+ def replica_configuration?
147
+ @config[:replica] || @config[:slave]
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,152 @@
1
+ # frozen_string_literal: true
2
+
3
+ # For versions of Rails < 6.1
4
+
5
+ require 'delegate'
6
+ require 'active_record'
7
+ require 'active_record_host_pool/connection_adapter_mixin'
8
+
9
+ # this module sits in between ConnectionHandler and a bunch of different ConnectionPools (one per host).
10
+ # when a connection is requested, it goes like:
11
+ # ActiveRecordClass -> ConnectionHandler#connection
12
+ # ConnectionHandler#connection -> (find or create PoolProxy)
13
+ # PoolProxy -> shared list of Pools
14
+ # Pool actually gives back a connection, then PoolProxy turns this
15
+ # into a ConnectionProxy that can inform (on execute) which db we should be on.
16
+
17
+ module ActiveRecordHostPool
18
+ # Sits between ConnectionHandler and a bunch of different ConnectionPools (one per host).
19
+ class PoolProxy < Delegator
20
+ def initialize(spec)
21
+ super(spec)
22
+ @spec = spec
23
+ @config = spec.config
24
+ end
25
+
26
+ def __getobj__
27
+ _connection_pool
28
+ end
29
+
30
+ def __setobj__(spec)
31
+ @spec = spec
32
+ @config = spec.config
33
+ @_pool_key = nil
34
+ end
35
+
36
+ attr_reader :spec
37
+
38
+ def connection(*args)
39
+ real_connection = _connection_pool.connection(*args)
40
+ _connection_proxy_for(real_connection, @config[:database])
41
+ rescue Mysql2::Error, ActiveRecord::NoDatabaseError
42
+ _connection_pools.delete(_pool_key)
43
+ Kernel.raise
44
+ end
45
+
46
+ # by the time we are patched into ActiveRecord, the current thread has already established
47
+ # a connection. thus we need to patch both connection and checkout/checkin
48
+ def checkout(*args, &block)
49
+ cx = _connection_pool.checkout(*args, &block)
50
+ _connection_proxy_for(cx, @config[:database])
51
+ end
52
+
53
+ def checkin(cx)
54
+ cx = cx.unproxied
55
+ _connection_pool.checkin(cx)
56
+ end
57
+
58
+ def with_connection
59
+ cx = checkout
60
+ yield cx
61
+ ensure
62
+ checkin cx
63
+ end
64
+
65
+ def disconnect!
66
+ p = _connection_pool(false)
67
+ return unless p
68
+
69
+ p.disconnect!
70
+ p.automatic_reconnect = true if p.respond_to?(:automatic_reconnect=)
71
+ _clear_connection_proxy_cache
72
+ end
73
+
74
+ def automatic_reconnect=(value)
75
+ p = _connection_pool(false)
76
+ return unless p
77
+
78
+ p.automatic_reconnect = value if p.respond_to?(:automatic_reconnect=)
79
+ end
80
+
81
+ def clear_reloadable_connections!
82
+ _connection_pool.clear_reloadable_connections!
83
+ _clear_connection_proxy_cache
84
+ end
85
+
86
+ def release_connection(*args)
87
+ p = _connection_pool(false)
88
+ return unless p
89
+
90
+ p.release_connection(*args)
91
+ end
92
+
93
+ def flush!
94
+ p = _connection_pool(false)
95
+ return unless p
96
+
97
+ p.flush!
98
+ end
99
+
100
+ def discard!
101
+ p = _connection_pool(false)
102
+ return unless p
103
+
104
+ p.discard!
105
+
106
+ # All connections in the pool (even if they're currently
107
+ # leased!) have just been discarded, along with the pool itself.
108
+ # Any further interaction with the pool (except #spec and #schema_cache)
109
+ # is undefined.
110
+ # Remove the connection for the given key so a new one can be created in its place
111
+ _connection_pools.delete(_pool_key)
112
+ end
113
+
114
+ private
115
+
116
+ def _connection_pools
117
+ @@_connection_pools ||= {}
118
+ end
119
+
120
+ def _pool_key
121
+ @_pool_key ||= "#{@config[:host]}/#{@config[:port]}/#{@config[:socket]}/" \
122
+ "#{@config[:username]}/#{replica_configuration? && 'replica'}"
123
+ end
124
+
125
+ def _connection_pool(auto_create = true)
126
+ pool = _connection_pools[_pool_key]
127
+ if pool.nil? && auto_create
128
+ pool = _connection_pools[_pool_key] = ActiveRecord::ConnectionAdapters::ConnectionPool.new(@spec)
129
+ end
130
+ pool
131
+ end
132
+
133
+ def _connection_proxy_for(connection, database)
134
+ @connection_proxy_cache ||= {}
135
+ key = [connection, database]
136
+
137
+ @connection_proxy_cache[key] ||= begin
138
+ cx = ActiveRecordHostPool::ConnectionProxy.new(connection, database)
139
+ cx.execute('select 1')
140
+ cx
141
+ end
142
+ end
143
+
144
+ def _clear_connection_proxy_cache
145
+ @connection_proxy_cache = {}
146
+ end
147
+
148
+ def replica_configuration?
149
+ @config[:replica] || @config[:slave]
150
+ end
151
+ end
152
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecordHostPool
4
- VERSION = "1.1.0"
4
+ VERSION = "1.2.0"
5
5
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_host_pool
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Quorning
8
8
  - Gabe Martin-Dempesy
9
9
  - Pierre Schambacher
10
10
  - Ben Osheroff
11
- autorequire:
11
+ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2022-08-26 00:00:00.000000000 Z
14
+ date: 2022-10-13 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activerecord
@@ -22,7 +22,7 @@ dependencies:
22
22
  version: 5.1.0
23
23
  - - "<"
24
24
  - !ruby/object:Gem::Version
25
- version: '7.0'
25
+ version: '7.1'
26
26
  type: :runtime
27
27
  prerelease: false
28
28
  version_requirements: !ruby/object:Gem::Requirement
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: 5.1.0
33
33
  - - "<"
34
34
  - !ruby/object:Gem::Version
35
- version: '7.0'
35
+ version: '7.1'
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: mysql2
38
38
  requirement: !ruby/object:Gem::Requirement
@@ -163,6 +163,8 @@ files:
163
163
  - lib/active_record_host_pool/connection_adapter_mixin.rb
164
164
  - lib/active_record_host_pool/connection_proxy.rb
165
165
  - lib/active_record_host_pool/pool_proxy.rb
166
+ - lib/active_record_host_pool/pool_proxy_6_1.rb
167
+ - lib/active_record_host_pool/pool_proxy_legacy.rb
166
168
  - lib/active_record_host_pool/version.rb
167
169
  - test/database.yml
168
170
  - test/helper.rb
@@ -172,7 +174,7 @@ homepage: https://github.com/zendesk/active_record_host_pool
172
174
  licenses:
173
175
  - MIT
174
176
  metadata: {}
175
- post_install_message:
177
+ post_install_message:
176
178
  rdoc_options: []
177
179
  require_paths:
178
180
  - lib
@@ -187,8 +189,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
189
  - !ruby/object:Gem::Version
188
190
  version: '0'
189
191
  requirements: []
190
- rubygems_version: 3.1.6
191
- signing_key:
192
+ rubygems_version: 3.0.3.1
193
+ signing_key:
192
194
  specification_version: 4
193
195
  summary: Allow ActiveRecord to share a connection to multiple databases on the same
194
196
  host