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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ee008476f444de984ef7413b21bee87043d9e5e87a7eabf85a934cf74b147225
4
- data.tar.gz: 1dd10b9b77c9dc4109f6a8e779c970fc6f7ee2e4880cecb467ab3060ecc4f571
3
+ metadata.gz: 570ab8b29056f8831e828d18b114f49cf708b9350a7a0b6fd20645d73d3cd6c2
4
+ data.tar.gz: 246a625f56ca744cada699f99b631651d814232cafdf9fca6bf4b0c70d1e2b37
5
5
  SHA512:
6
- metadata.gz: 32cc154c5df5d6501de5bf93daf32857448645b9fe5071bec84b51dbda86cf0efd1fe6cddfd24707fda8201e7d6b8fb10c02f3c7e2bf108226b50a4cbe1b65fd
7
- data.tar.gz: ad2630d6736bc49490ccb2eec83da4878dd4b349e9e06cd12f5d9f62a10109922a379c0dab43aa5a0c8a3f33241ca71f6c6ba24386cc6a7cf097db1397ef2518
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
@@ -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
@@ -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
@@ -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
@@ -2,5 +2,5 @@
2
2
 
3
3
  module PGMQ
4
4
  # Current version of the pgmq-ruby gem
5
- VERSION = "0.7.0"
5
+ VERSION = "0.7.2"
6
6
  end
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", "~> 2.4"
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.0
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.10
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: []