pgmq-ruby 0.7.0 → 0.7.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/CHANGELOG.md +20 -0
- data/lib/pgmq/client/consumer.rb +1 -2
- data/lib/pgmq/client/maintenance.rb +5 -7
- data/lib/pgmq/client.rb +10 -0
- data/lib/pgmq/connection.rb +20 -0
- data/lib/pgmq/queue_name.rb +2 -3
- data/lib/pgmq/version.rb +1 -1
- data/pgmq-ruby.gemspec +1 -1
- metadata +10 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 570ab8b29056f8831e828d18b114f49cf708b9350a7a0b6fd20645d73d3cd6c2
|
|
4
|
+
data.tar.gz: 246a625f56ca744cada699f99b631651d814232cafdf9fca6bf4b0c70d1e2b37
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f88edaa90fde3e5bfc585f3e22702c1a0545d0b807d7ae8807dc39bd4ea3dd1f0857a55885b6d3122332fe5a8a06a7e0d282a65524aee6e89e8f04882e0b0792
|
|
7
|
+
data.tar.gz: 06a01af44cfa4dd807ec23eaff5985c4fd72a3c2363f9b6706c89a8b6bf2e6c348cb71a176e23f7010ba7643210f8c461dc541865ede37b82888fa67e057ff04
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.2 (2026-08-31)
|
|
4
|
+
|
|
5
|
+
### Dependencies
|
|
6
|
+
- **[Change]** Loosen the `connection_pool` runtime dependency from `~> 2.4` to `>= 2.4, < 4` so applications can
|
|
7
|
+
upgrade to `connection_pool` 3.x. The gem only uses `ConnectionPool.new(size:, timeout:)`, `#with`, `#shutdown`,
|
|
8
|
+
`#reload`, `#available` and the `TimeoutError` / `PoolShuttingDownError` classes, all of which are unchanged in 3.x
|
|
9
|
+
(the 3.0 breaking change was positional-to-keyword arguments on `#checkout` / `#reap`, which are not used here).
|
|
10
|
+
The lockfile now resolves to 3.0.2 so CI exercises the new major.
|
|
11
|
+
|
|
12
|
+
## 0.7.1 (2026-07-09)
|
|
13
|
+
|
|
14
|
+
### Connection Pool
|
|
15
|
+
- **[Feature]** Add `PGMQ::Connection#reload` (and `PGMQ::Client#reload`, which delegates to it). It drops every
|
|
16
|
+
connection currently in the pool and lets the pool rebuild fresh ones lazily on the next checkout — unlike `#close`,
|
|
17
|
+
which shuts the pool down permanently. Use it to recover from a connection that libpq still reports as
|
|
18
|
+
`CONNECTION_OK` but is in fact wedged, e.g. after a wall-clock `Timeout.timeout` interrupted a query mid-flight and
|
|
19
|
+
left the socket poisoned so it re-hangs on reuse. `#verify_connection!` cannot catch that case (the connection does
|
|
20
|
+
not report `CONNECTION_BAD`), so the caller must discard it explicitly; `reload` is the safe, pool-wide way to do so.
|
|
21
|
+
Connections it drops are closed. Implemented via `ConnectionPool#reload`.
|
|
22
|
+
|
|
3
23
|
## 0.7.0 (2026-06-15)
|
|
4
24
|
|
|
5
25
|
### Queue Naming
|
data/lib/pgmq/client/consumer.rb
CHANGED
|
@@ -235,8 +235,6 @@ module PGMQ
|
|
|
235
235
|
# next), `read_grouped_head` surfaces the leading edge of every group in one call - useful for detecting
|
|
236
236
|
# head-of-line stalls or building per-group progress dashboards.
|
|
237
237
|
#
|
|
238
|
-
# @note Requires PGMQ v1.11.1+.
|
|
239
|
-
#
|
|
240
238
|
# @param queue_name [String] name of the queue
|
|
241
239
|
# @param vt [Integer] visibility timeout in seconds
|
|
242
240
|
# @param qty [Integer] maximum number of groups to sample
|
|
@@ -254,6 +252,7 @@ module PGMQ
|
|
|
254
252
|
# heads.each do |msg|
|
|
255
253
|
# alert_if_stuck(msg) if msg.enqueued_at < Time.now - 3600
|
|
256
254
|
# end
|
|
255
|
+
# @note Requires PGMQ v1.11.1+.
|
|
257
256
|
def read_grouped_head(queue_name, vt: DEFAULT_VT, qty: 1)
|
|
258
257
|
validate_queue_name!(queue_name)
|
|
259
258
|
|
|
@@ -66,10 +66,6 @@ module PGMQ
|
|
|
66
66
|
# If the archive table is already partitioned the function returns without error (idempotent). If the archive
|
|
67
67
|
# table does not exist it also returns without error.
|
|
68
68
|
#
|
|
69
|
-
# @note Requires the `pg_partman` PostgreSQL extension. If pg_partman is not installed and the archive table
|
|
70
|
-
# exists, the call raises `PGMQ::Errors::ConnectionError`. If the archive table does not exist the call
|
|
71
|
-
# succeeds (returns nil) without touching pg_partman, so no extension is needed in that case.
|
|
72
|
-
#
|
|
73
69
|
# @param queue_name [String] name of the queue whose archive table to convert
|
|
74
70
|
# @param partition_interval [String] partition interval passed to pg_partman (default: "10000" rows or a time
|
|
75
71
|
# expression such as "daily" / "1 month")
|
|
@@ -87,6 +83,9 @@ module PGMQ
|
|
|
87
83
|
# partition_interval: "daily",
|
|
88
84
|
# retention_interval: "30 days"
|
|
89
85
|
# )
|
|
86
|
+
# @note Requires the `pg_partman` PostgreSQL extension. If pg_partman is not installed and the archive table
|
|
87
|
+
# exists, the call raises `PGMQ::Errors::ConnectionError`. If the archive table does not exist the call
|
|
88
|
+
# succeeds (returns nil) without touching pg_partman, so no extension is needed in that case.
|
|
90
89
|
def convert_archive_partitioned(
|
|
91
90
|
queue_name,
|
|
92
91
|
partition_interval: "10000",
|
|
@@ -185,9 +184,6 @@ module PGMQ
|
|
|
185
184
|
# The return value mirrors `PG::Connection#wait_for_notify`: the channel name string on success,
|
|
186
185
|
# or `nil` on timeout.
|
|
187
186
|
#
|
|
188
|
-
# @note Orchestration (retry loop, reconnect-on-drop, graceful shutdown) is the caller's responsibility.
|
|
189
|
-
# This method is a thin primitive — it listens once, waits, and returns.
|
|
190
|
-
#
|
|
191
187
|
# @param queue_name [String] name of the queue (must have notifications enabled via {#enable_notify_insert})
|
|
192
188
|
# @param timeout [Numeric, nil] seconds to wait; `nil` blocks indefinitely
|
|
193
189
|
# @return [String, nil] notification channel name, or `nil` if the timeout expired
|
|
@@ -205,6 +201,8 @@ module PGMQ
|
|
|
205
201
|
# client.wait_for_notify("orders", timeout: 5) do |channel, pid, payload|
|
|
206
202
|
# puts "Notified on #{channel} by backend #{pid}"
|
|
207
203
|
# end
|
|
204
|
+
# @note Orchestration (retry loop, reconnect-on-drop, graceful shutdown) is the caller's responsibility.
|
|
205
|
+
# This method is a thin primitive - it listens once, waits, and returns.
|
|
208
206
|
def wait_for_notify(queue_name, timeout: nil)
|
|
209
207
|
validate_queue_name!(queue_name)
|
|
210
208
|
# PGMQ trigger fires pg_notify('pgmq.q_<queue>.INSERT', NULL)
|
data/lib/pgmq/client.rb
CHANGED
|
@@ -84,6 +84,16 @@ module PGMQ
|
|
|
84
84
|
@connection.close
|
|
85
85
|
end
|
|
86
86
|
|
|
87
|
+
# Drops every pooled connection and rebuilds lazily on the next checkout, leaving the pool usable (unlike {#close}).
|
|
88
|
+
# Use it to discard a connection that reports +CONNECTION_OK+ but is actually wedged - e.g. after a wall-clock
|
|
89
|
+
# timeout interrupted a query mid-flight and left the socket poisoned so it would re-hang on reuse. See
|
|
90
|
+
# {PGMQ::Connection#reload}.
|
|
91
|
+
#
|
|
92
|
+
# @return [void]
|
|
93
|
+
def reload
|
|
94
|
+
@connection.reload
|
|
95
|
+
end
|
|
96
|
+
|
|
87
97
|
# Returns connection pool statistics
|
|
88
98
|
#
|
|
89
99
|
# @return [Hash] statistics about the connection pool
|
data/lib/pgmq/connection.rb
CHANGED
|
@@ -178,6 +178,26 @@ module PGMQ
|
|
|
178
178
|
@pool.shutdown { |conn| conn.close unless conn.finished? }
|
|
179
179
|
end
|
|
180
180
|
|
|
181
|
+
# Drops every connection currently in the pool and lets the pool build fresh ones lazily on the next checkout.
|
|
182
|
+
# Unlike {#close} (which shuts the pool down permanently), the pool stays usable afterwards.
|
|
183
|
+
#
|
|
184
|
+
# Use this to recover from a connection that libpq still reports as +CONNECTION_OK+ but which is in fact wedged -
|
|
185
|
+
# e.g. after a wall-clock timeout (+Timeout.timeout+) interrupted a query mid-flight, leaving the socket poisoned so
|
|
186
|
+
# it re-hangs on reuse. {#verify_connection!} cannot catch that case (the connection does not report
|
|
187
|
+
# +CONNECTION_BAD+), so the caller must discard it explicitly; +reload+ is the safe, pool-wide way to do so.
|
|
188
|
+
#
|
|
189
|
+
# @return [void]
|
|
190
|
+
# @example Discard the pool after a query had to be force-interrupted
|
|
191
|
+
# begin
|
|
192
|
+
# Timeout.timeout(5) { connection.with_connection { |conn| conn.exec("SELECT ...") } }
|
|
193
|
+
# rescue Timeout::Error
|
|
194
|
+
# connection.reload # drop the possibly-poisoned pooled connections
|
|
195
|
+
# raise
|
|
196
|
+
# end
|
|
197
|
+
def reload
|
|
198
|
+
@pool.reload { |conn| conn.close unless conn.finished? }
|
|
199
|
+
end
|
|
200
|
+
|
|
181
201
|
# Returns connection pool statistics
|
|
182
202
|
#
|
|
183
203
|
# @return [Hash] statistics about the connection pool
|
data/lib/pgmq/queue_name.rb
CHANGED
|
@@ -126,13 +126,12 @@ module PGMQ
|
|
|
126
126
|
# a digit), truncates to fit {MAX_LENGTH}, and falls back to {SANITIZE_FALLBACK} when nothing usable remains. The
|
|
127
127
|
# return value always satisfies {.valid?}.
|
|
128
128
|
#
|
|
129
|
+
# @param name [String, #to_s] arbitrary input
|
|
130
|
+
# @return [String] a guaranteed-valid queue name
|
|
129
131
|
# @note Because it coerces rather than rejects, distinct inputs can map to the *same* name (e.g. +"a/b"+ and
|
|
130
132
|
# +"a-b"+ both become +"a_b"+; +"!!!"+ and +""+ both become +"queue"+). If your name selects a queue table,
|
|
131
133
|
# that means two logically different inputs could share one queue. When that matters - especially for untrusted
|
|
132
134
|
# input - prefer {.sanitize!}, which raises instead of substituting.
|
|
133
|
-
#
|
|
134
|
-
# @param name [String, #to_s] arbitrary input
|
|
135
|
-
# @return [String] a guaranteed-valid queue name
|
|
136
135
|
def sanitize(name)
|
|
137
136
|
cleaned = name.to_s.downcase
|
|
138
137
|
.gsub(/[^a-z0-9_]+/, "_").squeeze("_")
|
data/lib/pgmq/version.rb
CHANGED
data/pgmq-ruby.gemspec
CHANGED
|
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
|
|
|
26
26
|
spec.require_paths = ["lib"]
|
|
27
27
|
|
|
28
28
|
# Runtime dependencies
|
|
29
|
-
spec.add_dependency "connection_pool", "
|
|
29
|
+
spec.add_dependency "connection_pool", ">= 2.4", "< 4"
|
|
30
30
|
spec.add_dependency "pg", "~> 1.5"
|
|
31
31
|
spec.add_dependency "zeitwerk", "~> 2.6"
|
|
32
32
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pgmq-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.7.
|
|
4
|
+
version: 0.7.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Maciej Mensfeld
|
|
@@ -13,16 +13,22 @@ dependencies:
|
|
|
13
13
|
name: connection_pool
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "
|
|
16
|
+
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
18
|
version: '2.4'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '4'
|
|
19
22
|
type: :runtime
|
|
20
23
|
prerelease: false
|
|
21
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
25
|
requirements:
|
|
23
|
-
- - "
|
|
26
|
+
- - ">="
|
|
24
27
|
- !ruby/object:Gem::Version
|
|
25
28
|
version: '2.4'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '4'
|
|
26
32
|
- !ruby/object:Gem::Dependency
|
|
27
33
|
name: pg
|
|
28
34
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -107,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
107
113
|
- !ruby/object:Gem::Version
|
|
108
114
|
version: '0'
|
|
109
115
|
requirements: []
|
|
110
|
-
rubygems_version: 4.0.
|
|
116
|
+
rubygems_version: 4.0.16
|
|
111
117
|
specification_version: 4
|
|
112
118
|
summary: Ruby client for PGMQ (Postgres Message Queue)
|
|
113
119
|
test_files: []
|