active_record_host_pool 4.2.0 → 4.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3944318de7c004909c8bc75a447e01e9ec1c5a44d0eb99f0449cc53880ec0d74
4
- data.tar.gz: 1b0ec3c13a90206c9a2f02a6c0c51b92a9053ba3858a979268eea071c52c26ae
3
+ metadata.gz: fced473565b601f6ec0a0e682b254c251d653c10be16690c46470d418dd9f346
4
+ data.tar.gz: 7281ce45c44d5209f16444e55caaaf4c2a059981d6a41a48d45d0f394c08b4a3
5
5
  SHA512:
6
- metadata.gz: b9742fce5b0960f281e1e119f2e326b1b90a921f534da452f2fd67c289d18cbbdec6324dafab53e6053745f5a5bd69f01b927dcde2005fe6daaab184943758de
7
- data.tar.gz: 69766e4f3747c105c4b98b86609faa3cb9eee8105951faa82627da8117c4eb36f66c4b5edf34e59f6fb44b25c0a47ca9242065de1eef65dcc15636a7188312bd
6
+ metadata.gz: a053ec7e487686f9ab3aa0b5c01912292aee086f3d9e2444e715c99f9ef278c564b2a48b8eceb68030972c10ac20c04b20745689e88efdd9ae333256a033a371
7
+ data.tar.gz: d6f6bc52d1e46987faf4b7d57b7e6df43464e60ed978b3337056957f3e8d5b98ed1fc38f156ea1766b7c299ee1094a68e3ec6a13e8741117e311cb23d54ce385
data/Changelog.md CHANGED
@@ -6,6 +6,18 @@ and as of v1.0.0 this project adheres to [Semantic Versioning](https://semver.or
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [4.3.0]
10
+
11
+ ### Changed
12
+ - `.class_eval` now raises an exception when called on `ConnectionProxy`. Use `.arhp_connection_proxy_class_eval` if you _really_ need to modify the `ConnectionProxy` class.
13
+
14
+ ### Added
15
+ - Testing with Rails 8.1.
16
+
17
+ ### Removed
18
+ - `ConnectionProxy` no longer overrides `#class` to return the class of the proxied connection adapter.
19
+ - Support for Rails 7.1.
20
+
9
21
  ## [4.2.0]
10
22
 
11
23
  ### Changed
data/Readme.md CHANGED
@@ -53,18 +53,14 @@ Postgres, from an informal reading of the docs, will never support the concept o
53
53
  and make sure to require 'active_record_host_pool' in some way.
54
54
 
55
55
  ## Testing
56
- You need a local user called 'john-doe'.
57
56
 
58
- mysql -uroot
59
- CREATE USER 'john-doe'@'localhost';
60
- GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX ON *.* TO 'john-doe'@'localhost';
61
- FLUSH PRIVILEGES;
57
+ TestContainers will take care of setting up the necessary MySQL servers for you. You just need to have e.g. Docker running.
62
58
 
63
- With mysql running locally, run
59
+ Run e.g.
64
60
 
65
61
  BUNDLE_GEMFILE=gemfiles/rails6.1.gemfile bundle exec rake test
66
62
 
67
- Or
63
+ or
68
64
 
69
65
  BUNDLE_GEMFILE=gemfiles/rails6.1.gemfile ruby test/test_arhp.rb --seed 19911 --verbose
70
66
 
@@ -62,7 +62,7 @@ module ActiveRecordHostPool
62
62
  _desired_database_changed? ||
63
63
  _real_connection_changed?
64
64
  )
65
- log("select_db #{_host_pool_desired_database}", "SQL") do
65
+ log(select_db_log_arg, "SQL") do
66
66
  clear_cache!
67
67
  real_connection.select_db(_host_pool_desired_database)
68
68
  end
@@ -71,22 +71,23 @@ module ActiveRecordHostPool
71
71
  end
72
72
  end
73
73
 
74
+ if ActiveRecord.version < Gem::Version.new("8.2.a")
75
+ def select_db_log_arg
76
+ "select_db #{_host_pool_desired_database}"
77
+ end
78
+ else
79
+ def select_db_log_arg
80
+ ActiveRecord::ConnectionAdapters::QueryIntent.new(processed_sql: "select_db #{_host_pool_desired_database}")
81
+ end
82
+ end
83
+
74
84
  def _desired_database_changed?
75
85
  _host_pool_desired_database != @_cached_current_database
76
86
  end
77
87
 
78
- # rubocop:disable Lint/DuplicateMethods
79
- case "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
80
- when "7.1"
81
- def _real_connection_object_id
82
- @connection.object_id
83
- end
84
- else
85
- def _real_connection_object_id
86
- @raw_connection.object_id
87
- end
88
+ def _real_connection_object_id
89
+ @raw_connection.object_id
88
90
  end
89
- # rubocop:enable Lint/DuplicateMethods
90
91
 
91
92
  def _real_connection_changed?
92
93
  _real_connection_object_id != @_cached_connection_object_id
@@ -6,6 +6,16 @@ require "delegate"
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
+ class << self
10
+ def class_eval
11
+ raise "You probably want to call .class_eval on the ActiveRecord connection adapter and not on ActiveRecordHostPool's connection proxy. Use .arhp_connection_proxy_class_eval if you _really_ know what you're doing."
12
+ end
13
+
14
+ def arhp_connection_proxy_class_eval(...)
15
+ method(:class_eval).super_method.call(...)
16
+ end
17
+ end
18
+
9
19
  attr_reader :database
10
20
  def initialize(cx, database)
11
21
  super(cx)
@@ -26,11 +36,6 @@ module ActiveRecordHostPool
26
36
  @cx
27
37
  end
28
38
 
29
- # this is bad. I know. but it allows folks who class_eval on connection.class to do so
30
- def class
31
- @cx.class
32
- end
33
-
34
39
  def expects(*args)
35
40
  @cx.send(:expects, *args)
36
41
  end
@@ -51,35 +51,18 @@ module ActiveRecordHostPool
51
51
 
52
52
  attr_reader :pool_config
53
53
 
54
- # rubocop:disable Lint/DuplicateMethods
55
- case "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
56
- when "7.1"
57
- def connection(*args)
58
- real_connection = _unproxied_connection(*args)
59
- _connection_proxy_for(real_connection, @config[:database])
60
- rescue *RESCUABLE_DB_ERROR, ActiveRecord::NoDatabaseError, ActiveRecord::StatementInvalid
61
- _connection_pools.delete(_pool_key)
62
- Kernel.raise
63
- end
64
-
65
- def _unproxied_connection(*args)
66
- _connection_pool.connection(*args)
67
- end
68
- else
69
- def lease_connection(*args)
70
- real_connection = _unproxied_connection(*args)
71
- _connection_proxy_for(real_connection, @config[:database])
72
- rescue *RESCUABLE_DB_ERROR, ActiveRecord::NoDatabaseError, ActiveRecord::StatementInvalid
73
- _connection_pools.delete(_pool_key)
74
- Kernel.raise
75
- end
76
- alias_method :connection, :lease_connection
54
+ def lease_connection(*args)
55
+ real_connection = _unproxied_connection(*args)
56
+ _connection_proxy_for(real_connection, @config[:database])
57
+ rescue *RESCUABLE_DB_ERROR, ActiveRecord::NoDatabaseError, ActiveRecord::StatementInvalid
58
+ _connection_pools.delete(_pool_key)
59
+ Kernel.raise
60
+ end
61
+ alias_method :connection, :lease_connection
77
62
 
78
- def _unproxied_connection(*args)
79
- _connection_pool.lease_connection(*args)
80
- end
63
+ def _unproxied_connection(*args)
64
+ _connection_pool.lease_connection(*args)
81
65
  end
82
- # rubocop:enable Lint/DuplicateMethods
83
66
 
84
67
  # by the time we are patched into ActiveRecord, the current thread has already established
85
68
  # a connection. thus we need to patch both connection and checkout/checkin
@@ -93,49 +76,39 @@ module ActiveRecordHostPool
93
76
  _connection_pool.checkin(cx)
94
77
  end
95
78
 
96
- case "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
97
- when "7.1"
98
- def with_connection
99
- cx = checkout
100
- yield cx
101
- ensure
102
- checkin cx
103
- end
104
- else
105
- def with_connection(prevent_permanent_checkout: false) # rubocop:disable Lint/DuplicateMethods
106
- real_connection_lease = _connection_pool.send(:connection_lease)
107
- sticky_was = real_connection_lease.sticky
108
- real_connection_lease.sticky = false if prevent_permanent_checkout
109
-
110
- if real_connection_lease.connection
111
- begin
112
- yield _connection_proxy_for(real_connection_lease.connection, @config[:database])
113
- ensure
114
- real_connection_lease.sticky = sticky_was if prevent_permanent_checkout && !sticky_was
115
- end
116
- else
117
- begin
118
- real_connection_lease.connection = _unproxied_connection
119
- yield _connection_proxy_for(real_connection_lease.connection, @config[:database])
120
- ensure
121
- real_connection_lease.sticky = sticky_was if prevent_permanent_checkout && !sticky_was
122
- _connection_pool.release_connection(real_connection_lease) unless real_connection_lease.sticky
123
- end
124
- end
125
- end
79
+ def with_connection(prevent_permanent_checkout: false) # rubocop:disable Lint/DuplicateMethods
80
+ real_connection_lease = _connection_pool.send(:connection_lease)
81
+ sticky_was = real_connection_lease.sticky
82
+ real_connection_lease.sticky = false if prevent_permanent_checkout
126
83
 
127
- def active_connection?
128
- real_connection_lease = _connection_pool.send(:connection_lease)
129
- if real_connection_lease.connection
130
- _connection_proxy_for(real_connection_lease.connection, @config[:database])
84
+ if real_connection_lease.connection
85
+ begin
86
+ yield _connection_proxy_for(real_connection_lease.connection, @config[:database])
87
+ ensure
88
+ real_connection_lease.sticky = sticky_was if prevent_permanent_checkout && !sticky_was
89
+ end
90
+ else
91
+ begin
92
+ real_connection_lease.connection = _unproxied_connection
93
+ yield _connection_proxy_for(real_connection_lease.connection, @config[:database])
94
+ ensure
95
+ real_connection_lease.sticky = sticky_was if prevent_permanent_checkout && !sticky_was
96
+ _connection_pool.release_connection(real_connection_lease) unless real_connection_lease.sticky
131
97
  end
132
98
  end
133
- alias_method :active_connection, :active_connection?
99
+ end
134
100
 
135
- def schema_cache
136
- @schema_cache ||= ActiveRecord::ConnectionAdapters::BoundSchemaReflection.new(_connection_pool.schema_reflection, self)
101
+ def active_connection?
102
+ real_connection_lease = _connection_pool.send(:connection_lease)
103
+ if real_connection_lease.connection
104
+ _connection_proxy_for(real_connection_lease.connection, @config[:database])
137
105
  end
138
106
  end
107
+ alias_method :active_connection, :active_connection?
108
+
109
+ def schema_cache
110
+ @schema_cache ||= ActiveRecord::ConnectionAdapters::BoundSchemaReflection.new(_connection_pool.schema_reflection, self)
111
+ end
139
112
 
140
113
  def disconnect!
141
114
  p = _connection_pool(false)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecordHostPool
4
- VERSION = "4.2.0"
4
+ VERSION = "4.3.0"
5
5
  end
@@ -16,7 +16,6 @@ rescue LoadError
16
16
  :noop
17
17
  end
18
18
 
19
- require "active_record_host_pool/clear_query_cache_patch"
20
19
  require "active_record_host_pool/connection_proxy"
21
20
  require "active_record_host_pool/pool_proxy"
22
21
  require "active_record_host_pool/connection_adapter_mixin"
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.2.0
4
+ version: 4.3.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: 2025-04-18 00:00:00.000000000 Z
14
+ date: 2025-11-11 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activerecord
@@ -19,14 +19,14 @@ dependencies:
19
19
  requirements:
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: 7.1.0
22
+ version: 7.2.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 7.1.0
29
+ version: 7.2.0
30
30
  description: ''
31
31
  email:
32
32
  - bquorning@zendesk.com
@@ -42,7 +42,6 @@ files:
42
42
  - MIT-LICENSE
43
43
  - Readme.md
44
44
  - lib/active_record_host_pool.rb
45
- - lib/active_record_host_pool/clear_query_cache_patch.rb
46
45
  - lib/active_record_host_pool/connection_adapter_mixin.rb
47
46
  - lib/active_record_host_pool/connection_proxy.rb
48
47
  - lib/active_record_host_pool/pool_proxy.rb
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # ActiveRecord 6.0 introduced multiple database support. With that, an update
4
- # has been made in https://github.com/rails/rails/pull/35089 to ensure that
5
- # all query caches are cleared across connection handlers and pools. If you
6
- # write on one connection, the other connection will have the update that
7
- # occurred.
8
- #
9
- # This broke ARHP which implements its own pool, allowing you to access
10
- # multiple databases with the same connection (e.g. 1 connection for 100
11
- # shards on the same server).
12
- #
13
- # This patch maintains the reference to the database during the cache clearing
14
- # to ensure that the database doesn't get swapped out mid-way into an
15
- # operation.
16
- #
17
- # This is a private Rails API and may change in future releases as they're
18
- # actively working on sharding in Rails 6 and above.
19
- module ActiveRecordHostPool
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
- pool._unproxied_connection.clear_query_cache if pool.active_connection?
25
- end
26
- end
27
- end
28
- end
29
-
30
- case "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
31
- when "7.1"
32
- # Fix https://github.com/rails/rails/commit/401e2f24161ed6047ae33c322aaf6584b7728ab9
33
- ActiveRecord::Base.singleton_class.prepend(ActiveRecordHostPool::ClearQueryCachePatch)
34
- end