panda_pal 5.17.1 → 5.17.2
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/config/initializers/apartment.rb +20 -4
- data/lib/panda_pal/version.rb +1 -1
- data/spec/core/apartment_multidb_spec.rb +66 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1d2cfdbfc9d2c60cc080b545d2ee582ce212623a45c286d8610b8ac5f6c1af37
|
|
4
|
+
data.tar.gz: 4918d3bee6808bfbf22e98e23f3cbedcd493d4ec7c946ac67e0c8ca5485d9eca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0e06e419047c6a29e1ed8f03966bae4c31ed9e5b57ad6953133b890f6dab407d384ea1f071e0c88e01f7a69ef790f9b132f98a973aa3602b6b902d4871722799
|
|
7
|
+
data.tar.gz: 6d19e0a9ea13914f8045d62525dd73dcb97aadfc780dc1c4907fe3b80df9483144d1cc3cc087d509aa7cfba344aa64aaa4b7bd36b05fea354201d7e387094db4
|
|
@@ -148,10 +148,7 @@ module Apartment
|
|
|
148
148
|
|
|
149
149
|
raise ActiveRecord::StatementInvalid, "PandaPal/Apartment Mutli-DB support does not currently support DB roles" if ActiveRecord::Base.current_role != ActiveRecord::Base.default_role
|
|
150
150
|
|
|
151
|
-
unless
|
|
152
|
-
Apartment.establish_connection multi_tenantify(tenant, false)
|
|
153
|
-
Apartment.connection.verify!
|
|
154
|
-
end
|
|
151
|
+
establish_connection_pool(tenant) unless connection_pool_registered?
|
|
155
152
|
|
|
156
153
|
Apartment.connection.enable_query_cache! if query_cache_enabled
|
|
157
154
|
|
|
@@ -171,6 +168,25 @@ module Apartment
|
|
|
171
168
|
|
|
172
169
|
protected
|
|
173
170
|
|
|
171
|
+
ESTABLISH_CONNECTION_LOCK = Mutex.new
|
|
172
|
+
|
|
173
|
+
def connection_pool_registered?
|
|
174
|
+
!ActiveRecord::Base.connection_handler.retrieve_connection_pool(
|
|
175
|
+
ActiveRecord::Base.connection_specification_name,
|
|
176
|
+
role: ActiveRecord::Base.current_role,
|
|
177
|
+
shard: ActiveRecord::Base.current_shard,
|
|
178
|
+
).nil?
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def establish_connection_pool(tenant)
|
|
182
|
+
ESTABLISH_CONNECTION_LOCK.synchronize do
|
|
183
|
+
next if connection_pool_registered?
|
|
184
|
+
|
|
185
|
+
Apartment.establish_connection multi_tenantify(tenant, false)
|
|
186
|
+
Apartment.connection.verify!
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
174
190
|
def persistent_schemas
|
|
175
191
|
map_to_schemas(super)
|
|
176
192
|
end
|
data/lib/panda_pal/version.rb
CHANGED
|
@@ -53,6 +53,72 @@ RSpec.describe PandaPal::Organization, type: :model do
|
|
|
53
53
|
expect(PandaPal::ApiCall.connection.exec_query("SELECT current_database()").pluck("current_database")[0]).to eq("panda_pal_test2")
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
context "connection pool lifecycle" do
|
|
57
|
+
def alt_pool
|
|
58
|
+
ActiveRecord::Base.connection_handler.retrieve_connection_pool(
|
|
59
|
+
ActiveRecord::Base.connection_specification_name,
|
|
60
|
+
role: ActiveRecord::Base.current_role,
|
|
61
|
+
shard: "apt:alt",
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def count_establish_connection_calls
|
|
66
|
+
calls = Queue.new
|
|
67
|
+
allow(Apartment).to receive(:establish_connection).and_wrap_original do |original, *args, **kwargs|
|
|
68
|
+
calls << true
|
|
69
|
+
original.call(*args, **kwargs)
|
|
70
|
+
end
|
|
71
|
+
yield
|
|
72
|
+
calls.size
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def switch_in_threads(tenant, count)
|
|
76
|
+
start = Queue.new
|
|
77
|
+
threads = count.times.map do
|
|
78
|
+
Thread.new do
|
|
79
|
+
start.pop
|
|
80
|
+
Apartment::Tenant.switch(tenant) { PandaPal::ApiCall.count }
|
|
81
|
+
ensure
|
|
82
|
+
ActiveRecord::Base.connection_handler.clear_active_connections!
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
count.times { start << true }
|
|
86
|
+
threads.map(&:value)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "reuses an existing shard pool whose connections have all been closed" do
|
|
90
|
+
org2.switch_tenant { PandaPal::ApiCall.count }
|
|
91
|
+
pool = alt_pool
|
|
92
|
+
ActiveRecord::Base.connection_handler.clear_active_connections!
|
|
93
|
+
pool.disconnect!
|
|
94
|
+
|
|
95
|
+
calls = count_establish_connection_calls do
|
|
96
|
+
org2.switch_tenant { expect(PandaPal::ApiCall.count).to eq(0) }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
expect(calls).to eq(0)
|
|
100
|
+
expect(alt_pool).to equal(pool)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "establishes a missing shard pool once when many threads need it at the same time" do
|
|
104
|
+
org2.switch_tenant { PandaPal::ApiCall.count }
|
|
105
|
+
ActiveRecord::Base.connection_handler.clear_active_connections!
|
|
106
|
+
ActiveRecord::Base.connection_handler.remove_connection_pool(
|
|
107
|
+
ActiveRecord::Base.connection_specification_name,
|
|
108
|
+
role: ActiveRecord::Base.current_role,
|
|
109
|
+
shard: "apt:alt",
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
results = nil
|
|
113
|
+
calls = count_establish_connection_calls do
|
|
114
|
+
results = switch_in_threads("alt:on_alt", 8)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
expect(results).to eq([0] * 8)
|
|
118
|
+
expect(calls).to eq(1)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
56
122
|
# load_async is a Rails 7.0+ feature.
|
|
57
123
|
context "load_async", skip: (ActiveRecord::Relation.method_defined?(:load_async) ? false : "requires Rails 7.0+ load_async") do
|
|
58
124
|
it "works across shards" do
|