pgbus 0.7.6 → 0.7.8
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 +1 -0
- data/lib/pgbus/active_job/executor.rb +11 -1
- data/lib/pgbus/event_bus/handler.rb +32 -3
- data/lib/pgbus/version.rb +1 -1
- 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: 48e02fc16de64a9ccec20b8b0d917e154e17dc2082c1e3933b80da1bdc2f0c2a
|
|
4
|
+
data.tar.gz: 811db2dfcb4c4271296d9125754af3865b117ebc8b45d3194bc4314cc43ffaba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2b41cd760d469af41c4e0ef0d9bfaffd3cb17ff81b38dbeb250605d78c737708f54ee43519fe25afeda83a5e15177a14e89e48d27471ae39ad5c79420d791e21
|
|
7
|
+
data.tar.gz: 50f209ed7b74e18c1bf927ca73fe80286c9a4333642af4f32e579bd6f9e40158007c07a39dfa6a3fc2082fd9ad1663f3e9b109ebd7021485f931a615ad9baabb
|
data/CHANGELOG.md
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
### Fixed
|
|
17
17
|
|
|
18
|
+
- **EventBus handler invocations now run inside `Rails.application.executor` (or `.reloader` in dev).** `Pgbus::EventBus::Handler#process` previously ran outside any Rails executor wrapper, so `claim_idempotency?`'s `ProcessedEvent.insert` (and any `handle` body that touches AR) leased a connection that was never returned to the pool. With a small AR pool (Rails dev default with `RAILS_MAX_THREADS=3` is 6 connections), a handful of consumed events leaked the entire pool. The next request that triggers `clear_reloadable_connections!` (any reloadable change in dev) hung in `with_exclusively_acquired_all_connections`, surfacing as a confusing `Rack::Timeout` with a trace ending in `MonitorMixin#wait_for_cond`. Mirrors the executor-wrap pattern already used by `Pgbus::ActiveJob::Executor#execute_job`. No-op when Rails isn't loaded.
|
|
18
19
|
- **Defensive retry on stale pooled pgmq connections in the enqueue path.** `Pgbus::Client#send_message`, `#send_batch`, and `#publish_to_topic` now retry once when `@pgmq.produce*` raises `PGMQ::Errors::ConnectionError` with a message indicating the pooled `PG::Connection` was killed beneath pgmq-ruby — typically by PgBouncer hitting `server_idle_timeout` / `client_idle_timeout`, an admin disconnect, or a TCP RST. Observed in production as `PQsocket() can't get socket descriptor` on the first produce following an idle window. pgmq-ruby's `auto_reconnect` recovers on the *next* pool checkout, so a single retry is sufficient; non-stale errors (pool timeout, misconfiguration, unreachable database) still propagate unchanged. Upstream pgmq-ruby fix for the underlying misclassification is in-flight at mensfeld/pgmq-ruby#94.
|
|
19
20
|
|
|
20
21
|
## [0.5.1] - 2026-04-08
|
|
@@ -107,12 +107,22 @@ module Pgbus
|
|
|
107
107
|
|
|
108
108
|
def execute_job(job)
|
|
109
109
|
if defined?(Rails) && Rails.respond_to?(:application) && Rails.application
|
|
110
|
-
Rails.application.
|
|
110
|
+
wrapper = reloading? ? Rails.application.reloader : Rails.application.executor
|
|
111
|
+
wrapper.wrap { job.perform_now }
|
|
111
112
|
else
|
|
112
113
|
job.perform_now
|
|
113
114
|
end
|
|
114
115
|
end
|
|
115
116
|
|
|
117
|
+
def reloading?
|
|
118
|
+
app_config = Rails.application.config
|
|
119
|
+
if app_config.respond_to?(:enable_reloading)
|
|
120
|
+
app_config.enable_reloading
|
|
121
|
+
else
|
|
122
|
+
!app_config.cache_classes
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
116
126
|
def monotonic_now
|
|
117
127
|
::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
|
|
118
128
|
end
|
|
@@ -18,6 +18,16 @@ module Pgbus
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def process(message)
|
|
21
|
+
with_rails_executor { process!(message) }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def handle(event)
|
|
25
|
+
raise NotImplementedError, "#{self.class.name} must implement #handle(event)"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def process!(message)
|
|
21
31
|
raw = JSON.parse(message.message)
|
|
22
32
|
event = build_event(raw)
|
|
23
33
|
|
|
@@ -28,11 +38,30 @@ module Pgbus
|
|
|
28
38
|
:handled
|
|
29
39
|
end
|
|
30
40
|
|
|
31
|
-
|
|
32
|
-
|
|
41
|
+
# Mirrors Pgbus::ActiveJob::Executor#execute_job: wrap the handler
|
|
42
|
+
# invocation in Rails.application.executor (or the reloader in dev)
|
|
43
|
+
# so AR connections leased by `claim_idempotency?` and `handle` are
|
|
44
|
+
# released back to the pool when this method returns. Without the
|
|
45
|
+
# wrap, every consumed event leaks one AR connection on the consumer
|
|
46
|
+
# thread — in dev that wedges `clear_reloadable_connections!`,
|
|
47
|
+
# producing a confusing Rack::Timeout in `MonitorMixin#wait_for_cond`.
|
|
48
|
+
#
|
|
49
|
+
# No-op when Rails isn't loaded (test harnesses, gem-only consumers).
|
|
50
|
+
def with_rails_executor(&)
|
|
51
|
+
return yield unless defined?(Rails) && Rails.respond_to?(:application) && Rails.application
|
|
52
|
+
|
|
53
|
+
wrapper = reloading? ? Rails.application.reloader : Rails.application.executor
|
|
54
|
+
wrapper.wrap(&)
|
|
33
55
|
end
|
|
34
56
|
|
|
35
|
-
|
|
57
|
+
def reloading?
|
|
58
|
+
app_config = Rails.application.config
|
|
59
|
+
if app_config.respond_to?(:enable_reloading)
|
|
60
|
+
app_config.enable_reloading
|
|
61
|
+
else
|
|
62
|
+
!app_config.cache_classes
|
|
63
|
+
end
|
|
64
|
+
end
|
|
36
65
|
|
|
37
66
|
def build_event(raw)
|
|
38
67
|
payload = raw["payload"]
|
data/lib/pgbus/version.rb
CHANGED