pgbus 0.17.2 → 0.18.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 +10 -0
- data/README.md +55 -9
- data/Rakefile +26 -0
- data/app/assets/javascripts/pgbus/stream_source_element.js +37 -4
- data/app/assets/javascripts/pgbus/stream_source_element.min.js +6 -0
- data/app/assets/javascripts/pgbus/stream_source_element.min.js.map +1 -0
- data/app/controllers/pgbus/frontends_controller.rb +25 -11
- data/app/frontend/pgbus/application.min.js +2 -0
- data/app/frontend/pgbus/application.min.js.map +1 -0
- data/app/frontend/pgbus/modules/charts.js +24 -6
- data/app/frontend/pgbus/modules/charts.min.js +2 -0
- data/app/frontend/pgbus/modules/charts.min.js.map +1 -0
- data/app/frontend/pgbus/vendor/turbo.min.js +54 -0
- data/app/frontend/pgbus/vendor/turbo.min.js.map +1 -0
- data/app/views/layouts/pgbus/application.html.erb +0 -1
- data/config/routes.rb +1 -1
- data/lib/generators/pgbus/add_presence_generator.rb +2 -1
- data/lib/generators/pgbus/add_presence_seats_generator.rb +45 -0
- data/lib/generators/pgbus/templates/add_presence.rb.erb +32 -7
- data/lib/generators/pgbus/templates/add_presence_seats.rb.erb +38 -0
- data/lib/pgbus/configuration/presence_settings.rb +103 -0
- data/lib/pgbus/configuration/stream_authorization.rb +36 -0
- data/lib/pgbus/configuration.rb +16 -1
- data/lib/pgbus/engine.rb +13 -7
- data/lib/pgbus/generators/migration_detector.rb +9 -1
- data/lib/pgbus/streams/envelope.rb +3 -2
- data/lib/pgbus/streams/presence.rb +317 -81
- data/lib/pgbus/version.rb +1 -1
- data/lib/pgbus/web/stream_app.rb +43 -14
- data/lib/pgbus/web/streamer/connection.rb +26 -9
- data/lib/pgbus/web/streamer/falcon_connection.rb +23 -9
- data/lib/pgbus/web/streamer/heartbeat.rb +9 -3
- data/lib/pgbus/web/streamer/instance.rb +25 -8
- data/lib/pgbus/web/streamer/peer_close_watcher.rb +183 -0
- data/lib/pgbus/web/streamer/presence_tracker.rb +155 -0
- data/lib/pgbus/web/streamer/stream_event_dispatcher.rb +26 -39
- data/lib/pgbus.rb +2 -0
- metadata +15 -1
|
@@ -105,6 +105,7 @@ module Pgbus
|
|
|
105
105
|
# process-wide setting. Falls back to the global config
|
|
106
106
|
# for production call sites that don't specify one.
|
|
107
107
|
@config = config || Pgbus.configuration
|
|
108
|
+
@presence = PresenceTracker.new(config: @config, presence_provider: @presence_provider, logger: @logger)
|
|
108
109
|
# Two write deadlines (issue #315 item 3). Fanout writes run serially
|
|
109
110
|
# on this single thread, so a slow client stalls the connections
|
|
110
111
|
# queued behind it — the short fanout deadline bounds that stall.
|
|
@@ -400,6 +401,16 @@ module Pgbus
|
|
|
400
401
|
@stream_counter.increment_connections(stream)
|
|
401
402
|
@registry.register(connection)
|
|
402
403
|
presence_join(connection, stream)
|
|
404
|
+
# Step 6: announce the connection id only now (issue #521). A
|
|
405
|
+
# client that writes keyed by it right after pgbus:connected
|
|
406
|
+
# (Presence#set_state) must find the registered connection and
|
|
407
|
+
# its presence row. If that write finds the socket gone, run the
|
|
408
|
+
# disconnect now rather than leave the connection registered,
|
|
409
|
+
# and its seat on the roster, until the next heartbeat. A later
|
|
410
|
+
# DisconnectMessage for it (heartbeat, peer-close watcher) is a
|
|
411
|
+
# no-op: unregister reports false and the seat has already left.
|
|
412
|
+
connection.write_connected
|
|
413
|
+
handle_disconnect(DisconnectMessage.new(connection: connection)) if connection.dead?
|
|
403
414
|
end
|
|
404
415
|
|
|
405
416
|
record_stat(
|
|
@@ -408,10 +419,12 @@ module Pgbus
|
|
|
408
419
|
started_at: started_at
|
|
409
420
|
)
|
|
410
421
|
rescue StandardError => e
|
|
411
|
-
# Same leak path for exceptions in steps 1-
|
|
422
|
+
# Same leak path for exceptions in steps 1-6. Mark dead and
|
|
412
423
|
# scrub state so a transient failure on a single connect
|
|
413
424
|
# doesn't permanently bloat @full_to_logical or leave a
|
|
414
|
-
# dangling LISTEN on the PG connection.
|
|
425
|
+
# dangling LISTEN on the PG connection. A connection already
|
|
426
|
+
# registered in step 5 is dead now, so the heartbeat sweep
|
|
427
|
+
# unregisters it (and leaves its seat) like any dead connection.
|
|
415
428
|
remove_in_flight(stream, connection)
|
|
416
429
|
@scanned_cursor.delete(connection)
|
|
417
430
|
cleanup_stream_if_unused(stream)
|
|
@@ -428,6 +441,10 @@ module Pgbus
|
|
|
428
441
|
@stream_counter.decrement_connections(stream) if removed
|
|
429
442
|
presence_leave(connection, stream)
|
|
430
443
|
cleanup_stream_if_unused(stream)
|
|
444
|
+
# A second DisconnectMessage for the same connection (heartbeat,
|
|
445
|
+
# peer-close watcher, a failed pgbus:connected write) is a no-op
|
|
446
|
+
# and must not count as another disconnect.
|
|
447
|
+
return unless removed
|
|
431
448
|
|
|
432
449
|
record_stat(
|
|
433
450
|
stream_name: stream,
|
|
@@ -436,19 +453,11 @@ module Pgbus
|
|
|
436
453
|
)
|
|
437
454
|
end
|
|
438
455
|
|
|
439
|
-
# Touches
|
|
440
|
-
#
|
|
441
|
-
# still-connected members don't get swept
|
|
442
|
-
# presence member (non-presence streams, anonymous) are skipped.
|
|
456
|
+
# Touches the presence rows of the given connections and expires
|
|
457
|
+
# silent seats. Posted by the Heartbeat each tick so idle but
|
|
458
|
+
# still-connected members don't get swept (see PresenceTracker).
|
|
443
459
|
def handle_presence_touch(msg)
|
|
444
|
-
msg.connections
|
|
445
|
-
member_id = presence_member_of(connection)
|
|
446
|
-
next unless member_id
|
|
447
|
-
|
|
448
|
-
@presence_provider.call(connection.stream_name).touch(member_id: member_id)
|
|
449
|
-
rescue StandardError => e
|
|
450
|
-
@logger.error { "[Pgbus::Streamer::StreamEventDispatcher] presence touch failed: #{e.class}: #{e.message}" }
|
|
451
|
-
end
|
|
460
|
+
@presence.touch(msg.connections)
|
|
452
461
|
end
|
|
453
462
|
|
|
454
463
|
# If this stream has no remaining subscribers (registered or
|
|
@@ -640,35 +649,13 @@ module Pgbus
|
|
|
640
649
|
connection.respond_to?(:id) && connection.id.to_s == exclude.to_s
|
|
641
650
|
end
|
|
642
651
|
|
|
643
|
-
# Connection-driven presence (
|
|
644
|
-
# the stream is configured for presence and the connection's
|
|
645
|
-
# authorize-context yields a member id. Stores the member id on the
|
|
646
|
-
# connection so handle_disconnect/handle_presence_touch can act on
|
|
647
|
-
# it. Failures are logged and swallowed: a presence DB hiccup must
|
|
648
|
-
# not knock a live SSE connection out of the registry.
|
|
652
|
+
# Connection-driven presence (issues #169, #515): see PresenceTracker.
|
|
649
653
|
def presence_join(connection, stream)
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
member = @config.presence_member_for(connection.context)
|
|
653
|
-
return unless member
|
|
654
|
-
|
|
655
|
-
@presence_provider.call(stream).join(member_id: member[:id], metadata: member[:metadata] || {})
|
|
656
|
-
connection.presence_member = member[:id] if connection.respond_to?(:presence_member=)
|
|
657
|
-
rescue StandardError => e
|
|
658
|
-
@logger.error { "[Pgbus::Streamer::StreamEventDispatcher] presence join failed: #{e.class}: #{e.message}" }
|
|
654
|
+
@presence.join(connection, stream)
|
|
659
655
|
end
|
|
660
656
|
|
|
661
657
|
def presence_leave(connection, stream)
|
|
662
|
-
|
|
663
|
-
return unless member_id
|
|
664
|
-
|
|
665
|
-
@presence_provider.call(stream).leave(member_id: member_id)
|
|
666
|
-
rescue StandardError => e
|
|
667
|
-
@logger.error { "[Pgbus::Streamer::StreamEventDispatcher] presence leave failed: #{e.class}: #{e.message}" }
|
|
668
|
-
end
|
|
669
|
-
|
|
670
|
-
def presence_member_of(connection)
|
|
671
|
-
connection.respond_to?(:presence_member) ? connection.presence_member : nil
|
|
658
|
+
@presence.leave(connection, stream)
|
|
672
659
|
end
|
|
673
660
|
|
|
674
661
|
def monotonic_ms
|
data/lib/pgbus.rb
CHANGED
|
@@ -289,8 +289,10 @@ module Pgbus
|
|
|
289
289
|
# Do NOT call close — the parent's @pgmq_mutex is in undefined
|
|
290
290
|
# state post-fork and attempting to acquire it can deadlock.
|
|
291
291
|
# The next call to Pgbus.client will lazily create a fresh one.
|
|
292
|
+
# Cached streams hold the client they were built with, so they go too.
|
|
292
293
|
def reset_client!
|
|
293
294
|
@client = nil
|
|
295
|
+
@stream_cache = nil
|
|
294
296
|
end
|
|
295
297
|
|
|
296
298
|
def logger
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pgbus
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.18.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mikael Henriksson
|
|
@@ -123,6 +123,8 @@ files:
|
|
|
123
123
|
- README.md
|
|
124
124
|
- Rakefile
|
|
125
125
|
- app/assets/javascripts/pgbus/stream_source_element.js
|
|
126
|
+
- app/assets/javascripts/pgbus/stream_source_element.min.js
|
|
127
|
+
- app/assets/javascripts/pgbus/stream_source_element.min.js.map
|
|
126
128
|
- app/controllers/concerns/pgbus/job_listing.rb
|
|
127
129
|
- app/controllers/concerns/pgbus/process_listing.rb
|
|
128
130
|
- app/controllers/pgbus/api/insights_controller.rb
|
|
@@ -143,11 +145,17 @@ files:
|
|
|
143
145
|
- app/controllers/pgbus/queues_controller.rb
|
|
144
146
|
- app/controllers/pgbus/recurring_tasks_controller.rb
|
|
145
147
|
- app/frontend/pgbus/application.js
|
|
148
|
+
- app/frontend/pgbus/application.min.js
|
|
149
|
+
- app/frontend/pgbus/application.min.js.map
|
|
146
150
|
- app/frontend/pgbus/modules/charts.js
|
|
151
|
+
- app/frontend/pgbus/modules/charts.min.js
|
|
152
|
+
- app/frontend/pgbus/modules/charts.min.js.map
|
|
147
153
|
- app/frontend/pgbus/style.css
|
|
148
154
|
- app/frontend/pgbus/tailwind.css
|
|
149
155
|
- app/frontend/pgbus/vendor/apexcharts.js
|
|
150
156
|
- app/frontend/pgbus/vendor/turbo.js
|
|
157
|
+
- app/frontend/pgbus/vendor/turbo.min.js
|
|
158
|
+
- app/frontend/pgbus/vendor/turbo.min.js.map
|
|
151
159
|
- app/helpers/pgbus/application_helper.rb
|
|
152
160
|
- app/helpers/pgbus/button_helper.rb
|
|
153
161
|
- app/helpers/pgbus/dashboard_helper.rb
|
|
@@ -244,6 +252,7 @@ files:
|
|
|
244
252
|
- lib/generators/pgbus/add_job_stats_queue_index_generator.rb
|
|
245
253
|
- lib/generators/pgbus/add_outbox_generator.rb
|
|
246
254
|
- lib/generators/pgbus/add_presence_generator.rb
|
|
255
|
+
- lib/generators/pgbus/add_presence_seats_generator.rb
|
|
247
256
|
- lib/generators/pgbus/add_processed_event_completion_generator.rb
|
|
248
257
|
- lib/generators/pgbus/add_queue_states_generator.rb
|
|
249
258
|
- lib/generators/pgbus/add_recurring_generator.rb
|
|
@@ -261,6 +270,7 @@ files:
|
|
|
261
270
|
- lib/generators/pgbus/templates/add_job_stats_queue_index.rb.erb
|
|
262
271
|
- lib/generators/pgbus/templates/add_outbox.rb.erb
|
|
263
272
|
- lib/generators/pgbus/templates/add_presence.rb.erb
|
|
273
|
+
- lib/generators/pgbus/templates/add_presence_seats.rb.erb
|
|
264
274
|
- lib/generators/pgbus/templates/add_processed_event_completion.rb.erb
|
|
265
275
|
- lib/generators/pgbus/templates/add_queue_states.rb.erb
|
|
266
276
|
- lib/generators/pgbus/templates/add_recurring_tables.rb.erb
|
|
@@ -305,6 +315,8 @@ files:
|
|
|
305
315
|
- lib/pgbus/concurrency/semaphore.rb
|
|
306
316
|
- lib/pgbus/configuration.rb
|
|
307
317
|
- lib/pgbus/configuration/capsule_dsl.rb
|
|
318
|
+
- lib/pgbus/configuration/presence_settings.rb
|
|
319
|
+
- lib/pgbus/configuration/stream_authorization.rb
|
|
308
320
|
- lib/pgbus/current_attributes.rb
|
|
309
321
|
- lib/pgbus/database_tasks_guard.rb
|
|
310
322
|
- lib/pgbus/dead_letter_header.rb
|
|
@@ -466,6 +478,8 @@ files:
|
|
|
466
478
|
- lib/pgbus/web/streamer/master_hub.rb
|
|
467
479
|
- lib/pgbus/web/streamer/master_hub_boot.rb
|
|
468
480
|
- lib/pgbus/web/streamer/outbound_pump.rb
|
|
481
|
+
- lib/pgbus/web/streamer/peer_close_watcher.rb
|
|
482
|
+
- lib/pgbus/web/streamer/presence_tracker.rb
|
|
469
483
|
- lib/pgbus/web/streamer/registry.rb
|
|
470
484
|
- lib/pgbus/web/streamer/stream_counter.rb
|
|
471
485
|
- lib/pgbus/web/streamer/stream_event_dispatcher.rb
|