pgbus 0.2.8 → 0.2.9

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: ef44191dc6dab011a25d7ab69e0a8ad9ab5432b48301ba6d4e54f65afbb52c61
4
- data.tar.gz: c75c9857c9889b206b09974d920fee96023ba1b1280e7d1734ff833095833c84
3
+ metadata.gz: 6674a7ff09a30f7bc774f46d1f43754e3371b8831422251cbe97b6f660ce6d78
4
+ data.tar.gz: 5993390e26fb669327a037a7e6885fad88f7d9ab6985f6fbdbdd88d94175608d
5
5
  SHA512:
6
- metadata.gz: 686c4aa7e111ce5d1a82b82d135bf37da2f8321142f8d09b522c06800e5a4a386b259ddac62e6666043b363a44345b57c444bd0656c6010f39e12ad3722a50a0
7
- data.tar.gz: ade1d916918327f0680d4d029444da9f91d8da86e8210497c59e0bf5a0962bdad370eff8dbee3dacbd1207b040c9c3f8c80c28c80abd507b9a4122012078a949
6
+ metadata.gz: f434f3ab52040cf1ece892472a0b61f0b6af83073e7bab45f467a15649a576870ccec972d6c908be60dd560bfec67ce87acdd6f973ac07e4b51ffee5705e6e34
7
+ data.tar.gz: 11f903c2ad03c2a2f1ae4333bf2ada15a34933e4712ab161e209b519a032d8d90aa163dbf40a101481084f37234f3b5acccf3487844fc06730426f924688d3a2
@@ -12,11 +12,13 @@ module Pgbus
12
12
  def initialize(queues:, threads: 5, config: Pgbus.configuration,
13
13
  single_active_consumer: false, consumer_priority: 0)
14
14
  @queues = Array(queues)
15
+ @wildcard = @queues.include?("*")
15
16
  @threads = threads
16
17
  @config = config
17
18
  @single_active_consumer = single_active_consumer
18
19
  @consumer_priority = consumer_priority
19
20
  @lifecycle = Lifecycle.new
21
+ @last_wildcard_resolve = nil
20
22
  @jobs_processed = Concurrent::AtomicFixnum.new(0)
21
23
  @jobs_failed = Concurrent::AtomicFixnum.new(0)
22
24
  @in_flight = Concurrent::AtomicFixnum.new(0)
@@ -53,6 +55,7 @@ module Pgbus
53
55
  loop do
54
56
  process_signals
55
57
  check_recycle
58
+ refresh_wildcard_queues
56
59
 
57
60
  break if @lifecycle.stopped?
58
61
  break if @lifecycle.draining? && @pool.queue_length.zero?
@@ -79,6 +82,8 @@ module Pgbus
79
82
  @pool.kill
80
83
  end
81
84
 
85
+ WILDCARD_REFRESH_INTERVAL = 30 # seconds
86
+
82
87
  private
83
88
 
84
89
  def claim_and_execute
@@ -125,7 +130,11 @@ module Pgbus
125
130
  fetch_multi(active_queues, qty)
126
131
  end
127
132
  rescue StandardError => e
128
- Pgbus.logger.error { "[Pgbus] Error fetching messages: #{e.message}" }
133
+ if e.message.include?("does not exist") && e.message.include?("pgmq.q_")
134
+ evict_missing_queues(e)
135
+ else
136
+ Pgbus.logger.error { "[Pgbus] Error fetching messages: #{e.message}" }
137
+ end
129
138
  []
130
139
  end
131
140
 
@@ -184,9 +193,8 @@ module Pgbus
184
193
  end
185
194
 
186
195
  # Resolve "*" to all non-DLQ queues from pgmq.meta, stripping the prefix.
187
- # Called once at startup. If no wildcard, this is a no-op.
188
196
  def resolve_wildcard_queues
189
- return unless @queues.include?("*")
197
+ return unless @wildcard
190
198
 
191
199
  dlq_suffix = config.dead_letter_queue_suffix
192
200
  prefix = "#{config.queue_prefix}_"
@@ -201,12 +209,39 @@ module Pgbus
201
209
  Pgbus.logger.warn { "[Pgbus] Wildcard queue '*' resolved to no queues — falling back to default" }
202
210
  @queues = [config.default_queue]
203
211
  else
212
+ if @last_wildcard_resolve && resolved != @queues
213
+ Pgbus.logger.info { "[Pgbus] Wildcard queues changed: #{@queues.join(", ")} → #{resolved.join(", ")}" }
214
+ end
204
215
  @queues = resolved
205
- Pgbus.logger.info { "[Pgbus] Wildcard queue '*' resolved to: #{@queues.join(", ")}" }
216
+ Pgbus.logger.info { "[Pgbus] Wildcard queue '*' resolved to: #{@queues.join(", ")}" } unless @last_wildcard_resolve
206
217
  end
218
+ @last_wildcard_resolve = monotonic_now
207
219
  rescue StandardError => e
208
220
  Pgbus.logger.error { "[Pgbus] Failed to resolve wildcard queues: #{e.message} — falling back to default" }
209
- @queues = [config.default_queue]
221
+ @queues = [config.default_queue] unless @last_wildcard_resolve
222
+ end
223
+
224
+ # Periodically re-resolve wildcard queues to pick up new queues and
225
+ # drop deleted ones without requiring a worker restart.
226
+ def refresh_wildcard_queues
227
+ return unless @wildcard
228
+ return if @last_wildcard_resolve && (monotonic_now - @last_wildcard_resolve) < WILDCARD_REFRESH_INTERVAL
229
+
230
+ resolve_wildcard_queues
231
+ end
232
+
233
+ # When a "relation does not exist" error occurs, the queue was deleted.
234
+ # Extract the queue name from the error and remove it from the active list.
235
+ def evict_missing_queues(error)
236
+ prefix = "#{config.queue_prefix}_"
237
+ if error.message =~ /pgmq\.q_(\w+)/
238
+ physical_name = Regexp.last_match(1)
239
+ logical_name = physical_name.delete_prefix(prefix)
240
+ if @queues.delete(logical_name)
241
+ Pgbus.logger.warn { "[Pgbus] Evicted deleted queue '#{logical_name}' (#{physical_name}) from worker" }
242
+ end
243
+ end
244
+ Pgbus.logger.error { "[Pgbus] Queue table missing: #{error.message}" }
210
245
  end
211
246
 
212
247
  def check_recycle
@@ -287,6 +322,10 @@ module Pgbus
287
322
  restore_signals
288
323
  Pgbus.logger.info { "[Pgbus] Worker stopped. Processed: #{@jobs_processed.value}, Failed: #{@jobs_failed.value}" }
289
324
  end
325
+
326
+ def monotonic_now
327
+ ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
328
+ end
290
329
  end
291
330
  end
292
331
  end
data/lib/pgbus/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Pgbus
4
- VERSION = "0.2.8"
4
+ VERSION = "0.2.9"
5
5
  end
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.2.8
4
+ version: 0.2.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikael Henriksson