panda_pal 5.16.1 → 5.16.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 +68 -23
- data/lib/panda_pal/version.rb +1 -1
- data/spec/core/apartment_multidb_spec.rb +22 -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: 7c39df6be8d76f63ab12597a80696f629aac5da4a400adfa30119f303177251c
|
4
|
+
data.tar.gz: 2ab2639ea53d3e698244d65313f94b5ebc6c5edcb5039efc0b7dd801658a1603
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '06705595bcabf1959f7a2d72e7174d6944acc0876770878aa700d926d5b4beefdbb4a8af9462009a253d6eaf4a3fc3870f915291baa6490f5d2ecd756f84a275'
|
7
|
+
data.tar.gz: dac25e88efe02b2982e6441506e5d17328b3ee4500627d400523f37da6f7e6093c2a5d85492a73eb5946e616bc0ae7839730620ed66deb8986c952e416fc8f83
|
@@ -251,29 +251,6 @@ end
|
|
251
251
|
ActiveSupport::Cache::Store.send(:prepend, PandaPal::Plugins::ApartmentCache)
|
252
252
|
|
253
253
|
if defined?(ActionCable)
|
254
|
-
module ActionCable
|
255
|
-
module Channel
|
256
|
-
class Base
|
257
|
-
def self.broadcasting_for(model)
|
258
|
-
# Rails 5 #stream_for passes #channel_name as part of model. Rails 6 doesn't and includes it via #broadcasting_for.
|
259
|
-
model = [channel_name, model] unless model.is_a?(Array)
|
260
|
-
serialize_broadcasting([ Apartment::Tenant.current, model ])
|
261
|
-
end
|
262
|
-
|
263
|
-
def self.serialize_broadcasting(object)
|
264
|
-
case
|
265
|
-
when object.is_a?(Array)
|
266
|
-
object.map { |m| serialize_broadcasting(m) }.join(":")
|
267
|
-
when object.respond_to?(:to_gid_param)
|
268
|
-
object.to_gid_param
|
269
|
-
else
|
270
|
-
object.to_param
|
271
|
-
end
|
272
|
-
end
|
273
|
-
end
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
254
|
module PandaPal::Plugins::ActionCableApartment
|
278
255
|
module Connection
|
279
256
|
def tenant=(name)
|
@@ -283,13 +260,81 @@ if defined?(ActionCable)
|
|
283
260
|
def tenant
|
284
261
|
@tenant || 'public'
|
285
262
|
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
if Rails.version < '7.0'
|
267
|
+
module ActionCable
|
268
|
+
module Channel
|
269
|
+
class Base
|
270
|
+
def self.broadcasting_for(model)
|
271
|
+
# Rails 5 #stream_for passes #channel_name as part of model. Rails 6 doesn't and includes it via #broadcasting_for.
|
272
|
+
model = [channel_name, model] unless model.is_a?(Array)
|
273
|
+
serialize_broadcasting([ Apartment::Tenant.current, model ])
|
274
|
+
end
|
275
|
+
|
276
|
+
def self.serialize_broadcasting(object)
|
277
|
+
case
|
278
|
+
when object.is_a?(Array)
|
279
|
+
object.map { |m| serialize_broadcasting(m) }.join(":")
|
280
|
+
when object.respond_to?(:to_gid_param)
|
281
|
+
object.to_gid_param
|
282
|
+
else
|
283
|
+
object.to_param
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
286
289
|
|
290
|
+
module PandaPal::Plugins::ActionCableApartment::Connection
|
287
291
|
def dispatch_websocket_message(*args, **kwargs)
|
288
292
|
Apartment::Tenant.switch(tenant) do
|
289
293
|
super
|
290
294
|
end
|
291
295
|
end
|
292
296
|
end
|
297
|
+
else
|
298
|
+
module ActionCable
|
299
|
+
module Channel
|
300
|
+
class Base
|
301
|
+
def self.broadcasting_for(*args)
|
302
|
+
cconn = ActionCable.server.worker_pool.connection
|
303
|
+
items = [cconn&.tenant || Apartment::Tenant.current, channel_name, *args]
|
304
|
+
serialize_broadcasting(items)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
ActionCable::Server::Worker.set_callback :work, :around do |_, blk|
|
311
|
+
pten = Thread.current[:cable_tenant]
|
312
|
+
Thread.current[:cable_tenant] = connection.tenant
|
313
|
+
blk.call
|
314
|
+
ensure
|
315
|
+
Thread.current[:cable_tenant] = pten
|
316
|
+
end
|
317
|
+
|
318
|
+
if Apartment::Tenant.adapter.is_a?(Apartment::Adapters::PostgresqlSchemaAdapter)
|
319
|
+
module ApartmentConnPoolMixin
|
320
|
+
# Allows cable channels to lazy-load the tenant schema on first use
|
321
|
+
# (Using `switch` will ping the DB even if no queries are made)
|
322
|
+
def acquire_connection(...)
|
323
|
+
super.tap do |conn|
|
324
|
+
if ct = Thread.current[:cable_tenant]
|
325
|
+
Thread.current[:cable_tenant] = nil
|
326
|
+
adapter = Apartment::Tenant.adapter
|
327
|
+
# Apartment::Tenant.switch!(ct)
|
328
|
+
Thread.current[:cable_tenant] = ct
|
329
|
+
adapter.instance_variable_set(:@current, ct)
|
330
|
+
conn.schema_search_path = adapter.send :full_search_path
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
ActiveRecord::ConnectionAdapters::ConnectionPool.prepend(ApartmentConnPoolMixin)
|
337
|
+
end
|
293
338
|
end
|
294
339
|
|
295
340
|
ActionCable::Connection::Base.prepend(PandaPal::Plugins::ActionCableApartment::Connection)
|
data/lib/panda_pal/version.rb
CHANGED
@@ -31,6 +31,28 @@ RSpec.describe PandaPal::Organization, type: :model do
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
+
it "creates records on the target shard and schema" do
|
35
|
+
org1.switch_tenant
|
36
|
+
PandaPal::ApiCall.create!(logic: "from_primary")
|
37
|
+
expect(PandaPal::ApiCall.count).to eq(1)
|
38
|
+
expect(PandaPal::ApiCall.first.logic).to eq("from_primary")
|
39
|
+
|
40
|
+
org2.switch_tenant
|
41
|
+
PandaPal::ApiCall.create!(logic: "from_alt")
|
42
|
+
expect(PandaPal::ApiCall.count).to eq(1)
|
43
|
+
expect(PandaPal::ApiCall.first.logic).to eq("from_alt")
|
44
|
+
|
45
|
+
org1.switch_tenant
|
46
|
+
expect(PandaPal::ApiCall.count).to eq(1)
|
47
|
+
expect(PandaPal::ApiCall.first.logic).to eq("from_primary")
|
48
|
+
expect(PandaPal::ApiCall.connection.exec_query("SELECT current_database()").pluck("current_database")[0]).to eq("panda_pal_test1")
|
49
|
+
|
50
|
+
org2.switch_tenant
|
51
|
+
expect(PandaPal::ApiCall.count).to eq(1)
|
52
|
+
expect(PandaPal::ApiCall.first.logic).to eq("from_alt")
|
53
|
+
expect(PandaPal::ApiCall.connection.exec_query("SELECT current_database()").pluck("current_database")[0]).to eq("panda_pal_test2")
|
54
|
+
end
|
55
|
+
|
34
56
|
context "load_async" do
|
35
57
|
it "works across shards" do
|
36
58
|
qs = []
|