active_record_host_pool 1.2.5 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Changelog.md +115 -0
- data/Readme.md +3 -3
- data/lib/active_record_host_pool/clear_query_cache_patch.rb +13 -14
- data/lib/active_record_host_pool/connection_adapter_mixin.rb +49 -43
- data/lib/active_record_host_pool/connection_proxy.rb +14 -1
- data/lib/active_record_host_pool/pool_proxy.rb +182 -5
- data/lib/active_record_host_pool/version.rb +1 -1
- data/lib/active_record_host_pool.rb +21 -9
- metadata +8 -31
- data/lib/active_record_host_pool/pool_proxy_6_1.rb +0 -159
- data/lib/active_record_host_pool/pool_proxy_legacy.rb +0 -156
- data/test/database.yml +0 -108
- data/test/helper.rb +0 -198
- data/test/schema.rb +0 -23
- data/test/test_arhp.rb +0 -186
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6c85e552706dd86fe493aadff36c1c3cc6d9115ab9ee7bbfd627b3d684a02bd
|
4
|
+
data.tar.gz: 7effa38f67de9456d748027f27544bbc4f07afacba671c505dd8d23645648572
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8119ce55b8f44d7e29f195228c7055c1fe3c771916fc3ff31cc51e2db3ed7064c14db2424b6fdebf0a0a086e894cfb33faa97d87f1a16d272bff54957d3e20b0
|
7
|
+
data.tar.gz: 885cb1e3676d698f93394eb8686af27d5b2d2f2d194f3e533a3a20f3272678a08caf92d6819d08002c989f637430f8eb4d9fddd66d5bbbdccafbbd006da44c57
|
data/Changelog.md
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
|
+
and as of v1.0.0 this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
|
+
|
7
|
+
## [Unreleased]
|
8
|
+
|
9
|
+
## [2.0.0]
|
10
|
+
|
11
|
+
### Added
|
12
|
+
- Add support for Rails 7.1.
|
13
|
+
- `Trilogy` is now a supported MySQL database adapter. ActiveRecordHostPool no longer requires `mysql2`, nor does it explicitly require `activerecord-trilogy-adapter`. Applications using ARHP will now need to explicitly require one of these adapters in its gemfile. When using `activerecord-trilogy-adapter` also ensure that the `trilogy` gem is locked to `v2.5.0+`.
|
14
|
+
|
15
|
+
### Removed
|
16
|
+
- Remove `mysql2` as a direct dependency, test Rails 7.0 with `mysql2` and `activerecord-trilogy-adapter`.
|
17
|
+
- Remove support for Rails 5.1, 5.2, and 6.0.
|
18
|
+
|
19
|
+
### Fixed
|
20
|
+
- Implement equality for connection proxies to consider database; allows fixture loading for different databases
|
21
|
+
|
22
|
+
## [1.2.5] - 2023-07-14
|
23
|
+
### Added
|
24
|
+
- Start testing with Ruby 3.2.
|
25
|
+
|
26
|
+
### Removed
|
27
|
+
- Drop Ruby 2.6.
|
28
|
+
|
29
|
+
### Fixed
|
30
|
+
- Use a mutex inside `PoolProxy#disconnect!`. This might fix some `ActiveRecord::ConnectionNotEstablished` issues when a multi-threaded application is under heavy load. (Only applies when using Rails 6.1 or newer).
|
31
|
+
|
32
|
+
## [1.2.4] - 2023-03-20
|
33
|
+
### Fixed
|
34
|
+
- Fixed the warning when using `ruby2_keywords` on `execute_with_switching`.
|
35
|
+
- Simplified the `clear_query_caches_for_current_thread` patch.
|
36
|
+
|
37
|
+
## [1.2.3] - 2023-01-19
|
38
|
+
### Fixed
|
39
|
+
- Fix the patch for `ActiveRecord::Base.clear_query_caches_for_current_thread` to work correctly right after the creation of a new connection pool. (https://github.com/zendesk/active_record_host_pool/pull/105)
|
40
|
+
|
41
|
+
## [1.2.2] - 2023-01-18
|
42
|
+
### Added
|
43
|
+
- Add a new `ActiveRecordHostPool::PoolProxy#_unproxied_connection` method which gives access to the underlying, "real", shared connection without going through the connection proxy, which would call `#_host_pool_current_database=` on the underlying connection. (https://github.com/zendesk/active_record_host_pool/pull/104)
|
44
|
+
|
45
|
+
### Fixed
|
46
|
+
- Fix the patch for `ActiveRecord::Base.clear_on_handler` to work correctly right after the creation of a new connection pool. (https://github.com/zendesk/active_record_host_pool/pull/104)
|
47
|
+
|
48
|
+
## [1.2.1] - 2022-12-23
|
49
|
+
### Fixed
|
50
|
+
- Fix forwarding of kwargs when calling `#execute` in Rails 7. (https://github.com/zendesk/active_record_host_pool/pull/101)
|
51
|
+
|
52
|
+
## [1.2.0] - 2022-10-13
|
53
|
+
### Added
|
54
|
+
- Support for Rails 7.0 with [legacy_connection_handling=false and legacy_connection_handling=true](https://github.com/zendesk/active_record_host_pool/pull/95)
|
55
|
+
- Start testing with Ruby 3.0 & 3.1
|
56
|
+
|
57
|
+
## [1.1.1] - 2022-08-26
|
58
|
+
### Fixed
|
59
|
+
- Ensure that recently added files "lib/active_record_host_pool/pool_proxy_6_1.rb" and "lib/active_record_host_pool/pool_proxy_legacy.rb" are built into the shipped gem. (https://github.com/zendesk/active_record_host_pool/pull/92)
|
60
|
+
|
61
|
+
## [1.1.0] - 2022-08-26
|
62
|
+
### Added
|
63
|
+
- Support for Rails 6.1 with [legacy_connection_handling=false](https://github.com/zendesk/active_record_host_pool/pull/90) and [legacy_connection_handling=true](https://github.com/zendesk/active_record_host_pool/pull/88)
|
64
|
+
|
65
|
+
### Removed
|
66
|
+
- Removed compatibility with Rails 4.2. (https://github.com/zendesk/active_record_host_pool/pull/71)
|
67
|
+
- Removed compatibility with Ruby 2.5 and lower. (https://github.com/zendesk/active_record_host_pool/pull/80)
|
68
|
+
|
69
|
+
## [1.0.3] - 2021-02-09
|
70
|
+
### Fixed
|
71
|
+
- Add missing file to the released gem. (https://github.com/zendesk/active_record_host_pool/pull/68)
|
72
|
+
|
73
|
+
## [1.0.2] - 2021-02-09
|
74
|
+
### Fixed
|
75
|
+
- Fix unintended connection switching while clearing query cache in Rails 6.0. (https://github.com/zendesk/active_record_host_pool/pull/61)
|
76
|
+
|
77
|
+
## [1.0.1] - 2020-03-30
|
78
|
+
### Fixed
|
79
|
+
- Fix connection leakage when calling `release_connection` on pre-Rails 5 applications. (https://github.com/zendesk/active_record_host_pool/pull/58)
|
80
|
+
|
81
|
+
## [1.0.0] - 2020-02-25
|
82
|
+
### Added
|
83
|
+
- Support for Rails 6.0.x. (https://github.com/zendesk/active_record_host_pool/pull/53)
|
84
|
+
|
85
|
+
### Changed
|
86
|
+
- This gem now adheres to semantic versioning.
|
87
|
+
|
88
|
+
## [0.13.0] - 2019-08-26
|
89
|
+
### Added
|
90
|
+
- Support for Rails 5.2.3. (https://github.com/zendesk/active_record_host_pool/pull/48)
|
91
|
+
|
92
|
+
### Removed
|
93
|
+
- Removed testing with EOL Ruby 2.3 (https://github.com/zendesk/active_record_host_pool/pull/49)
|
94
|
+
|
95
|
+
## [0.12.0] - 2019-08-21
|
96
|
+
### Added
|
97
|
+
- Start testing with Ruby 2.5
|
98
|
+
- Update Gem ownership (https://github.com/zendesk/active_record_host_pool/pull/38)
|
99
|
+
|
100
|
+
### Removed
|
101
|
+
- Removed compatibility with Rails 3.2 and lower.
|
102
|
+
- Removed compatibility with Rails 5.0.
|
103
|
+
- Stop testing with Ruby 2.2.
|
104
|
+
|
105
|
+
## [0.11.0] - 2018-04-24
|
106
|
+
### Added
|
107
|
+
- Compatibility with Rails 5.1 (https://github.com/zendesk/active_record_host_pool/pull/31)
|
108
|
+
- Compatibility with Rails 5.2 (https://github.com/zendesk/active_record_host_pool/pull/32), (https://github.com/zendesk/active_record_host_pool/pull/34)
|
109
|
+
|
110
|
+
### Removed
|
111
|
+
- Removed support for the mysql gem, and only support mysql2 (https://github.com/zendesk/active_record_host_pool/pull/35)
|
112
|
+
|
113
|
+
## <= [0.10.1]
|
114
|
+
|
115
|
+
Unwritten
|
data/Readme.md
CHANGED
@@ -43,7 +43,7 @@ test_pool_2 => 127.0.0.1/3306//root/false
|
|
43
43
|
|
44
44
|
## Support
|
45
45
|
|
46
|
-
For now, the only backend known to work is MySQL, with the mysql2 gem.
|
46
|
+
For now, the only backend known to work is MySQL, with the mysql2 or activerecord-trilogy-adapter gem. When using the activerecord-trilogy-adapter ensure that the transitive dependency Trilogy is v2.5.0+.
|
47
47
|
Postgres, from an informal reading of the docs, will never support the concept of one server connection sharing multiple dbs.
|
48
48
|
|
49
49
|
## Installation
|
@@ -62,11 +62,11 @@ You need a local user called 'john-doe'.
|
|
62
62
|
|
63
63
|
With mysql running locally, run
|
64
64
|
|
65
|
-
BUNDLE_GEMFILE=gemfiles/
|
65
|
+
BUNDLE_GEMFILE=gemfiles/rails6.1.gemfile bundle exec rake test
|
66
66
|
|
67
67
|
Or
|
68
68
|
|
69
|
-
BUNDLE_GEMFILE=gemfiles/
|
69
|
+
BUNDLE_GEMFILE=gemfiles/rails6.1.gemfile ruby test/test_arhp.rb --seed 19911 --verbose
|
70
70
|
|
71
71
|
## Copyright
|
72
72
|
|
@@ -17,30 +17,29 @@
|
|
17
17
|
# This is a private Rails API and may change in future releases as they're
|
18
18
|
# actively working on sharding in Rails 6 and above.
|
19
19
|
module ActiveRecordHostPool
|
20
|
-
# For Rails
|
21
|
-
module
|
22
|
-
def
|
23
|
-
|
20
|
+
# For Rails 7.1.
|
21
|
+
module ClearQueryCachePatch
|
22
|
+
def clear_query_caches_for_current_thread
|
23
|
+
connection_handler.each_connection_pool do |pool|
|
24
24
|
pool._unproxied_connection.clear_query_cache if pool.active_connection?
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
# For Rails 6.0.
|
30
|
-
module
|
31
|
-
def
|
32
|
-
|
33
|
-
|
34
|
-
pool._unproxied_connection.clear_query_cache if pool.active_connection?
|
35
|
-
end
|
29
|
+
# For Rails 6.1 & 7.0.
|
30
|
+
module ClearOnHandlerPatch
|
31
|
+
def clear_on_handler(handler)
|
32
|
+
handler.all_connection_pools.each do |pool|
|
33
|
+
pool._unproxied_connection.clear_query_cache if pool.active_connection?
|
36
34
|
end
|
37
35
|
end
|
38
36
|
end
|
39
37
|
end
|
40
38
|
|
41
39
|
case "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
|
42
|
-
when
|
43
|
-
|
44
|
-
when '6.0'
|
40
|
+
when "7.1"
|
41
|
+
# Fix https://github.com/rails/rails/commit/401e2f24161ed6047ae33c322aaf6584b7728ab9
|
45
42
|
ActiveRecord::Base.singleton_class.prepend(ActiveRecordHostPool::ClearQueryCachePatch)
|
43
|
+
when "6.1", "7.0"
|
44
|
+
ActiveRecord::Base.singleton_class.prepend(ActiveRecordHostPool::ClearOnHandlerPatch)
|
46
45
|
end
|
@@ -1,6 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
case ActiveRecordHostPool.loaded_db_adapter
|
4
|
+
when :mysql2
|
5
|
+
require "active_record/connection_adapters/mysql2_adapter"
|
6
|
+
when :trilogy
|
7
|
+
case "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
|
8
|
+
when "6.1", "7.0"
|
9
|
+
require "trilogy_adapter/connection"
|
10
|
+
require "trilogy_adapter/errors"
|
11
|
+
ActiveRecord::Base.extend(TrilogyAdapter::Connection)
|
12
|
+
when "7.1"
|
13
|
+
require "active_record/connection_adapters/trilogy_adapter"
|
14
|
+
else
|
15
|
+
raise "Unsupported version of Rails (v#{ActiveRecord::VERSION::STRING})"
|
16
|
+
end
|
17
|
+
end
|
4
18
|
|
5
19
|
module ActiveRecordHostPool
|
6
20
|
module DatabaseSwitch
|
@@ -8,8 +22,16 @@ module ActiveRecordHostPool
|
|
8
22
|
base.class_eval do
|
9
23
|
attr_reader(:_host_pool_current_database)
|
10
24
|
|
11
|
-
|
12
|
-
|
25
|
+
# Patch `raw_execute` instead of `execute` since this commit:
|
26
|
+
# https://github.com/rails/rails/commit/f69bbcbc0752ca5d5af327d55922614a26f5c7e9
|
27
|
+
case "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
|
28
|
+
when "7.1"
|
29
|
+
alias_method :raw_execute_without_switching, :raw_execute
|
30
|
+
alias_method :raw_execute, :raw_execute_with_switching
|
31
|
+
else
|
32
|
+
alias_method :execute_without_switching, :execute
|
33
|
+
alias_method :execute, :execute_with_switching
|
34
|
+
end
|
13
35
|
|
14
36
|
alias_method :drop_database_without_no_switching, :drop_database
|
15
37
|
alias_method :drop_database, :drop_database_with_no_switching
|
@@ -34,13 +56,22 @@ module ActiveRecordHostPool
|
|
34
56
|
|
35
57
|
def self.ruby2_keywords(*); end unless respond_to?(:ruby2_keywords, true)
|
36
58
|
# This one really does need ruby2_keywords; in Rails 6.0 the method does not take
|
37
|
-
# any keyword arguments, but in Rails 7.0 it does. So, we don't know whether or not
|
59
|
+
# any keyword arguments, but in Rails 7.0+ it does. So, we don't know whether or not
|
38
60
|
# what we're delegating to takes kwargs, so ruby2_keywords is needed.
|
39
|
-
|
40
|
-
|
41
|
-
|
61
|
+
if ActiveRecord.version >= Gem::Version.new("7.1")
|
62
|
+
ruby2_keywords def raw_execute_with_switching(*args)
|
63
|
+
if _host_pool_current_database && !_no_switch
|
64
|
+
_switch_connection
|
65
|
+
end
|
66
|
+
raw_execute_without_switching(*args)
|
67
|
+
end
|
68
|
+
else
|
69
|
+
ruby2_keywords def execute_with_switching(*args)
|
70
|
+
if _host_pool_current_database && !_no_switch
|
71
|
+
_switch_connection
|
72
|
+
end
|
73
|
+
execute_without_switching(*args)
|
42
74
|
end
|
43
|
-
execute_without_switching(*args)
|
44
75
|
end
|
45
76
|
|
46
77
|
def drop_database_with_no_switching(*args)
|
@@ -69,10 +100,10 @@ module ActiveRecordHostPool
|
|
69
100
|
|
70
101
|
def _switch_connection
|
71
102
|
if _host_pool_current_database &&
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
103
|
+
(
|
104
|
+
(_host_pool_current_database != @_cached_current_database) ||
|
105
|
+
@connection.object_id != @_cached_connection_object_id
|
106
|
+
)
|
76
107
|
log("select_db #{_host_pool_current_database}", "SQL") do
|
77
108
|
clear_cache!
|
78
109
|
raw_connection.select_db(_host_pool_current_database)
|
@@ -97,36 +128,11 @@ module ActiveRecordHostPool
|
|
97
128
|
end
|
98
129
|
end
|
99
130
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
:noop
|
107
|
-
|
108
|
-
when '5.1', '5.2', '6.0'
|
109
|
-
|
110
|
-
def establish_connection(spec)
|
111
|
-
resolver = ConnectionAdapters::ConnectionSpecification::Resolver.new(Base.configurations)
|
112
|
-
spec = resolver.spec(spec)
|
113
|
-
|
114
|
-
owner_to_pool[spec.name] = ActiveRecordHostPool::PoolProxy.new(spec)
|
115
|
-
end
|
116
|
-
|
117
|
-
else
|
118
|
-
|
119
|
-
raise "Unsupported version of Rails (v#{ActiveRecord::VERSION::STRING})"
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
131
|
+
case ActiveRecordHostPool.loaded_db_adapter
|
132
|
+
when :mysql2
|
133
|
+
ActiveRecord::ConnectionAdapters::Mysql2Adapter.include(ActiveRecordHostPool::DatabaseSwitch)
|
134
|
+
when :trilogy
|
135
|
+
ActiveRecord::ConnectionAdapters::TrilogyAdapter.include(ActiveRecordHostPool::DatabaseSwitch)
|
123
136
|
end
|
124
137
|
|
125
|
-
ActiveRecord::ConnectionAdapters::
|
126
|
-
|
127
|
-
# In Rails 6.1 Connection Pools are no longer instantiated in #establish_connection but in a
|
128
|
-
# new pool method.
|
129
|
-
case "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
|
130
|
-
when '6.1', '7.0'
|
131
|
-
ActiveRecord::ConnectionAdapters::PoolConfig.prepend(ActiveRecordHostPool::PoolConfigPatch)
|
132
|
-
end
|
138
|
+
ActiveRecord::ConnectionAdapters::PoolConfig.prepend(ActiveRecordHostPool::PoolConfigPatch)
|
@@ -1,11 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "delegate"
|
4
4
|
|
5
5
|
# the ConnectionProxy sits between user-code and a real connection and says "I expect to be on this database"
|
6
6
|
# for each call to the connection. upon executing a statement, the connection will switch to that database.
|
7
7
|
module ActiveRecordHostPool
|
8
8
|
class ConnectionProxy < Delegator
|
9
|
+
attr_reader :database
|
9
10
|
def initialize(cx, database)
|
10
11
|
super(cx)
|
11
12
|
@cx = cx
|
@@ -52,6 +53,18 @@ module ActiveRecordHostPool
|
|
52
53
|
end
|
53
54
|
ruby2_keywords :send if respond_to?(:ruby2_keywords, true)
|
54
55
|
|
56
|
+
def ==(other)
|
57
|
+
self.class == other.class &&
|
58
|
+
other.respond_to?(:unproxied) && @cx == other.unproxied &&
|
59
|
+
other.respond_to?(:database) && @database == other.database
|
60
|
+
end
|
61
|
+
|
62
|
+
alias_method :eql?, :==
|
63
|
+
|
64
|
+
def hash
|
65
|
+
[self.class, @cx, @database].hash
|
66
|
+
end
|
67
|
+
|
55
68
|
private
|
56
69
|
|
57
70
|
def select(*args)
|
@@ -1,8 +1,185 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
require "delegate"
|
4
|
+
require "active_record"
|
5
|
+
require "active_record_host_pool/connection_adapter_mixin"
|
6
|
+
require "mutex_m"
|
7
|
+
|
8
|
+
# this module sits in between ConnectionHandler and a bunch of different ConnectionPools (one per host).
|
9
|
+
# when a connection is requested, it goes like:
|
10
|
+
# ActiveRecordClass -> ConnectionHandler#connection
|
11
|
+
# ConnectionHandler#connection -> (find or create PoolProxy)
|
12
|
+
# PoolProxy -> shared list of Pools
|
13
|
+
# Pool actually gives back a connection, then PoolProxy turns this
|
14
|
+
# into a ConnectionProxy that can inform (on execute) which db we should be on.
|
15
|
+
|
16
|
+
module ActiveRecordHostPool
|
17
|
+
# Sits between ConnectionHandler and a bunch of different ConnectionPools (one per host).
|
18
|
+
class PoolProxy < Delegator
|
19
|
+
include Mutex_m
|
20
|
+
|
21
|
+
case ActiveRecordHostPool.loaded_db_adapter
|
22
|
+
when :mysql2
|
23
|
+
RESCUABLE_DB_ERROR = Mysql2::Error
|
24
|
+
when :trilogy
|
25
|
+
RESCUABLE_DB_ERROR = Trilogy::ProtocolError
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(pool_config)
|
29
|
+
super(pool_config)
|
30
|
+
@pool_config = pool_config
|
31
|
+
@config = pool_config.db_config.configuration_hash
|
32
|
+
end
|
33
|
+
|
34
|
+
def __getobj__
|
35
|
+
_connection_pool
|
36
|
+
end
|
37
|
+
|
38
|
+
def __setobj__(pool_config)
|
39
|
+
@pool_config = pool_config
|
40
|
+
@config = pool_config.db_config.configuration_hash
|
41
|
+
@_pool_key = nil
|
42
|
+
end
|
43
|
+
|
44
|
+
attr_reader :pool_config
|
45
|
+
|
46
|
+
def connection(*args)
|
47
|
+
real_connection = _unproxied_connection(*args)
|
48
|
+
_connection_proxy_for(real_connection, @config[:database])
|
49
|
+
rescue RESCUABLE_DB_ERROR, ActiveRecord::NoDatabaseError, ActiveRecord::StatementInvalid
|
50
|
+
_connection_pools.delete(_pool_key)
|
51
|
+
Kernel.raise
|
52
|
+
end
|
53
|
+
|
54
|
+
def _unproxied_connection(*args)
|
55
|
+
_connection_pool.connection(*args)
|
56
|
+
end
|
57
|
+
|
58
|
+
# by the time we are patched into ActiveRecord, the current thread has already established
|
59
|
+
# a connection. thus we need to patch both connection and checkout/checkin
|
60
|
+
def checkout(*args, &block)
|
61
|
+
cx = _connection_pool.checkout(*args, &block)
|
62
|
+
_connection_proxy_for(cx, @config[:database])
|
63
|
+
end
|
64
|
+
|
65
|
+
def checkin(cx)
|
66
|
+
cx = cx.unproxied
|
67
|
+
_connection_pool.checkin(cx)
|
68
|
+
end
|
69
|
+
|
70
|
+
def with_connection
|
71
|
+
cx = checkout
|
72
|
+
yield cx
|
73
|
+
ensure
|
74
|
+
checkin cx
|
75
|
+
end
|
76
|
+
|
77
|
+
def disconnect!
|
78
|
+
p = _connection_pool(false)
|
79
|
+
return unless p
|
80
|
+
|
81
|
+
synchronize do
|
82
|
+
p.disconnect!
|
83
|
+
p.automatic_reconnect = true
|
84
|
+
_clear_connection_proxy_cache
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def automatic_reconnect=(value)
|
89
|
+
p = _connection_pool(false)
|
90
|
+
return unless p
|
91
|
+
|
92
|
+
p.automatic_reconnect = value
|
93
|
+
end
|
94
|
+
|
95
|
+
def clear_reloadable_connections!
|
96
|
+
_connection_pool.clear_reloadable_connections!
|
97
|
+
_clear_connection_proxy_cache
|
98
|
+
end
|
99
|
+
|
100
|
+
def release_connection(*args)
|
101
|
+
p = _connection_pool(false)
|
102
|
+
return unless p
|
103
|
+
|
104
|
+
p.release_connection(*args)
|
105
|
+
end
|
106
|
+
|
107
|
+
def flush!
|
108
|
+
p = _connection_pool(false)
|
109
|
+
return unless p
|
110
|
+
|
111
|
+
p.flush!
|
112
|
+
end
|
113
|
+
|
114
|
+
def discard!
|
115
|
+
p = _connection_pool(false)
|
116
|
+
return unless p
|
117
|
+
|
118
|
+
p.discard!
|
119
|
+
|
120
|
+
# All connections in the pool (even if they're currently
|
121
|
+
# leased!) have just been discarded, along with the pool itself.
|
122
|
+
# Any further interaction with the pool (except #pool_config and #schema_cache)
|
123
|
+
# is undefined.
|
124
|
+
# Remove the connection for the given key so a new one can be created in its place
|
125
|
+
_connection_pools.delete(_pool_key)
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
|
130
|
+
def _connection_pools
|
131
|
+
@@_connection_pools ||= {}
|
132
|
+
end
|
133
|
+
|
134
|
+
def _pool_key
|
135
|
+
@_pool_key ||= "#{@config[:host]}/#{@config[:port]}/#{@config[:socket]}/" \
|
136
|
+
"#{@config[:username]}/#{replica_configuration? && "replica"}"
|
137
|
+
end
|
138
|
+
|
139
|
+
def _connection_pool(auto_create = true)
|
140
|
+
pool = _connection_pools[_pool_key]
|
141
|
+
if pool.nil? && auto_create
|
142
|
+
pool = _connection_pools[_pool_key] = ActiveRecord::ConnectionAdapters::ConnectionPool.new(@pool_config)
|
143
|
+
end
|
144
|
+
pool
|
145
|
+
end
|
146
|
+
|
147
|
+
# Work around https://github.com/rails/rails/pull/48061/commits/63c0d6b31bcd0fc33745ec6fd278b2d1aab9be54
|
148
|
+
# standard:disable Lint/DuplicateMethods
|
149
|
+
case "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
|
150
|
+
when "6.1", "7.0"
|
151
|
+
def _connection_proxy_for(connection, database)
|
152
|
+
@connection_proxy_cache ||= {}
|
153
|
+
key = [connection, database]
|
154
|
+
|
155
|
+
@connection_proxy_cache[key] ||= begin
|
156
|
+
cx = ActiveRecordHostPool::ConnectionProxy.new(connection, database)
|
157
|
+
cx.execute("SELECT 1")
|
158
|
+
|
159
|
+
cx
|
160
|
+
end
|
161
|
+
end
|
162
|
+
else
|
163
|
+
def _connection_proxy_for(connection, database)
|
164
|
+
@connection_proxy_cache ||= {}
|
165
|
+
key = [connection, database]
|
166
|
+
|
167
|
+
@connection_proxy_cache[key] ||= begin
|
168
|
+
cx = ActiveRecordHostPool::ConnectionProxy.new(connection, database)
|
169
|
+
cx.raw_execute("SELECT 1", "ARHP SWITCH DB")
|
170
|
+
|
171
|
+
cx
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
# standard:enable Lint/DuplicateMethods
|
176
|
+
|
177
|
+
def _clear_connection_proxy_cache
|
178
|
+
@connection_proxy_cache = {}
|
179
|
+
end
|
180
|
+
|
181
|
+
def replica_configuration?
|
182
|
+
@config[:replica] || @config[:slave]
|
183
|
+
end
|
184
|
+
end
|
8
185
|
end
|
@@ -1,14 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
|
7
|
-
require 'active_record_host_pool/clear_query_cache_patch'
|
8
|
-
require 'active_record_host_pool/connection_proxy'
|
9
|
-
require 'active_record_host_pool/pool_proxy'
|
10
|
-
require 'active_record_host_pool/connection_adapter_mixin'
|
11
|
-
require 'active_record_host_pool/version'
|
3
|
+
require "active_record"
|
4
|
+
require "active_record/base"
|
5
|
+
require "active_record/connection_adapters/abstract_adapter"
|
12
6
|
|
13
7
|
module ActiveRecordHostPool
|
8
|
+
class << self
|
9
|
+
attr_accessor :loaded_db_adapter
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
if Gem.loaded_specs.include?("mysql2")
|
14
|
+
require "mysql2"
|
15
|
+
ActiveRecordHostPool.loaded_db_adapter = :mysql2
|
16
|
+
elsif Gem.loaded_specs.include?("trilogy")
|
17
|
+
require "trilogy"
|
18
|
+
require "activerecord-trilogy-adapter" if ActiveRecord.version < Gem::Version.new("7.1")
|
19
|
+
ActiveRecordHostPool.loaded_db_adapter = :trilogy
|
14
20
|
end
|
21
|
+
|
22
|
+
require "active_record_host_pool/clear_query_cache_patch"
|
23
|
+
require "active_record_host_pool/connection_proxy"
|
24
|
+
require "active_record_host_pool/pool_proxy"
|
25
|
+
require "active_record_host_pool/connection_adapter_mixin"
|
26
|
+
require "active_record_host_pool/version"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_record_host_pool
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Quorning
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2024-01-08 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activerecord
|
@@ -19,34 +19,20 @@ dependencies:
|
|
19
19
|
requirements:
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 6.1.0
|
23
23
|
- - "<"
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version: '7.
|
25
|
+
version: '7.2'
|
26
26
|
type: :runtime
|
27
27
|
prerelease: false
|
28
28
|
version_requirements: !ruby/object:Gem::Requirement
|
29
29
|
requirements:
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 6.1.0
|
33
33
|
- - "<"
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: '7.
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: mysql2
|
38
|
-
requirement: !ruby/object:Gem::Requirement
|
39
|
-
requirements:
|
40
|
-
- - ">="
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
version: '0'
|
43
|
-
type: :runtime
|
44
|
-
prerelease: false
|
45
|
-
version_requirements: !ruby/object:Gem::Requirement
|
46
|
-
requirements:
|
47
|
-
- - ">="
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: '0'
|
35
|
+
version: '7.2'
|
50
36
|
description: ''
|
51
37
|
email:
|
52
38
|
- bquorning@zendesk.com
|
@@ -58,6 +44,7 @@ extra_rdoc_files:
|
|
58
44
|
- MIT-LICENSE
|
59
45
|
- Readme.md
|
60
46
|
files:
|
47
|
+
- Changelog.md
|
61
48
|
- MIT-LICENSE
|
62
49
|
- Readme.md
|
63
50
|
- lib/active_record_host_pool.rb
|
@@ -65,13 +52,7 @@ files:
|
|
65
52
|
- lib/active_record_host_pool/connection_adapter_mixin.rb
|
66
53
|
- lib/active_record_host_pool/connection_proxy.rb
|
67
54
|
- lib/active_record_host_pool/pool_proxy.rb
|
68
|
-
- lib/active_record_host_pool/pool_proxy_6_1.rb
|
69
|
-
- lib/active_record_host_pool/pool_proxy_legacy.rb
|
70
55
|
- lib/active_record_host_pool/version.rb
|
71
|
-
- test/database.yml
|
72
|
-
- test/helper.rb
|
73
|
-
- test/schema.rb
|
74
|
-
- test/test_arhp.rb
|
75
56
|
homepage: https://github.com/zendesk/active_record_host_pool
|
76
57
|
licenses:
|
77
58
|
- MIT
|
@@ -96,8 +77,4 @@ signing_key:
|
|
96
77
|
specification_version: 4
|
97
78
|
summary: Allow ActiveRecord to share a connection to multiple databases on the same
|
98
79
|
host
|
99
|
-
test_files:
|
100
|
-
- test/database.yml
|
101
|
-
- test/helper.rb
|
102
|
-
- test/schema.rb
|
103
|
-
- test/test_arhp.rb
|
80
|
+
test_files: []
|