ask-state-providers 0.4.5 → 0.4.6

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: 39454f2f084a68e8741e42372f9fd84bb42764dd943788ad90705753b985bb56
4
- data.tar.gz: 1fc9f522ab52cfbfa6757f0b519e61c4d5eef53ebdec2e3a99fef266b461a309
3
+ metadata.gz: cb68f83181b30aa39191b2d19252a62231921b17aae87e1f3673bc0bb97cfacb
4
+ data.tar.gz: 8ffdbac8c8577c8934482c8ed7b2b8e96563e9994ba48770ecbe7c51b0eaca46
5
5
  SHA512:
6
- metadata.gz: e60207c2814ac955f0c2137966bb0a01b0bdf3743afc4441ee07a04a5e930584a773085a83c0883f963830e312525dc01ce262510b17e5fee73a7ab04104690a
7
- data.tar.gz: 26534c8ede214627d96f80e5eb83622c455c1c2ef9ed521dd306f683a791cd19bb92e9577de91f910d1d0361386ea101388135f6ea38db671cc06a93ec98535a
6
+ metadata.gz: '0907e2cbe480f8760546a6f5790ea19ab8c81694db591a864ebc4de4f538d1f1baecac436b91257f544ed93e8b9de7ffeaa9d396c118b7a63a87750167a69e62'
7
+ data.tar.gz: 42984849cf013942caf8fbc27a859abc40e37720bf5c26a60e92c4e435f0df0cb133f1c591ef0e88284ac5b342e451c084c34fd0eb55391200d9161163de6ec3
@@ -85,7 +85,7 @@ module Ask
85
85
  # -- key-value --
86
86
 
87
87
  def get(key)
88
- @pool.with do |conn|
88
+ with_connection do |conn|
89
89
  row = conn.exec_params(<<~SQL, [key, Time.now.utc])
90
90
  SELECT value FROM state_store
91
91
  WHERE key = $1 AND (expires_at IS NULL OR expires_at > $2)
@@ -95,7 +95,7 @@ module Ask
95
95
  end
96
96
 
97
97
  def set(key, value, ttl: nil)
98
- @pool.with do |conn|
98
+ with_connection do |conn|
99
99
  # Explicit casts: $3 is nil when no ttl, and PostgreSQL can't
100
100
  # infer a type for a bare NULL parameter.
101
101
  conn.exec_params(<<~SQL, [key, JSON.generate(value), ttl ? Time.now.utc + ttl : nil])
@@ -109,7 +109,7 @@ module Ask
109
109
  end
110
110
 
111
111
  def delete(key)
112
- @pool.with do |conn|
112
+ with_connection do |conn|
113
113
  conn.exec_params("DELETE FROM state_store WHERE key = $1", [key])
114
114
  # delete removes everything under the key, including ordered
115
115
  # lists (consumers store event feeds as lists).
@@ -118,7 +118,7 @@ module Ask
118
118
  end
119
119
 
120
120
  def set_if_not_exists(key, value, ttl: nil)
121
- @pool.with do |conn|
121
+ with_connection do |conn|
122
122
  now = Time.now.utc
123
123
  expires = ttl ? now + ttl : nil
124
124
 
@@ -143,7 +143,7 @@ module Ask
143
143
  end
144
144
 
145
145
  def clear
146
- @pool.with do |conn|
146
+ with_connection do |conn|
147
147
  conn.exec("DELETE FROM state_store")
148
148
  conn.exec("DELETE FROM locks")
149
149
  conn.exec("DELETE FROM queues")
@@ -152,7 +152,7 @@ module Ask
152
152
  end
153
153
 
154
154
  def exists?(key)
155
- @pool.with do |conn|
155
+ with_connection do |conn|
156
156
  result = conn.exec_params(<<~SQL, [key, Time.now.utc])
157
157
  SELECT 1 FROM state_store
158
158
  WHERE key = $1 AND (expires_at IS NULL OR expires_at > $2)
@@ -162,7 +162,7 @@ module Ask
162
162
  end
163
163
 
164
164
  def keys(pattern: nil)
165
- @pool.with do |conn|
165
+ with_connection do |conn|
166
166
  sql, params = if pattern
167
167
  like = self.class.glob_to_like(pattern)
168
168
  [<<~SQL, [like, Time.now.utc]]
@@ -186,7 +186,7 @@ module Ask
186
186
  expires_at_time = now + ttl
187
187
  token = SecureRandom.hex(16)
188
188
 
189
- acquired = @pool.with do |conn|
189
+ acquired = with_connection do |conn|
190
190
  # First clean up expired locks
191
191
  conn.exec_params("DELETE FROM locks WHERE key = $1 AND expires_at <= $2",
192
192
  [key, now])
@@ -206,7 +206,7 @@ module Ask
206
206
  end
207
207
 
208
208
  def release_lock(key, lock)
209
- @pool.with do |conn|
209
+ with_connection do |conn|
210
210
  result = conn.exec_params(
211
211
  "DELETE FROM locks WHERE key = $1 AND token = $2",
212
212
  [key, lock.token]
@@ -220,7 +220,7 @@ module Ask
220
220
  def enqueue(queue, value)
221
221
  id = SecureRandom.uuid
222
222
 
223
- @pool.with do |conn|
223
+ with_connection do |conn|
224
224
  conn.exec_params(<<~SQL, [queue, JSON.generate(value), Time.now.utc])
225
225
  INSERT INTO queues (queue_name, value, enqueued_at)
226
226
  VALUES ($1, $2, $3)
@@ -231,7 +231,7 @@ module Ask
231
231
  end
232
232
 
233
233
  def dequeue(queue)
234
- @pool.with do |conn|
234
+ with_connection do |conn|
235
235
  result = conn.exec_params(<<~SQL, [queue])
236
236
  DELETE FROM queues
237
237
  WHERE id = (
@@ -253,7 +253,7 @@ module Ask
253
253
  end
254
254
 
255
255
  def queue_depth(queue)
256
- @pool.with do |conn|
256
+ with_connection do |conn|
257
257
  result = conn.exec_params(
258
258
  "SELECT COUNT(*) AS cnt FROM queues WHERE queue_name = $1", [queue]
259
259
  )
@@ -264,7 +264,7 @@ module Ask
264
264
  # -- ordered lists --
265
265
 
266
266
  def list_append(key, value, max_length: nil)
267
- @pool.with do |conn|
267
+ with_connection do |conn|
268
268
  conn.exec_params(<<~SQL, [key, JSON.generate(value)])
269
269
  INSERT INTO lists (list_key, value)
270
270
  VALUES ($1, $2)
@@ -289,7 +289,7 @@ module Ask
289
289
  end
290
290
 
291
291
  def list_range(key, start = 0, stop = -1)
292
- @pool.with do |conn|
292
+ with_connection do |conn|
293
293
  rows = if stop == -1
294
294
  conn.exec_params(<<~SQL, [key, start])
295
295
  SELECT value FROM lists
@@ -312,7 +312,7 @@ module Ask
312
312
 
313
313
  def list_remove(key, value)
314
314
  serialized = JSON.generate(value)
315
- @pool.with do |conn|
315
+ with_connection do |conn|
316
316
  result = conn.exec_params(
317
317
  "DELETE FROM lists WHERE list_key = $1 AND value = $2",
318
318
  [key, serialized]
@@ -326,17 +326,29 @@ module Ask
326
326
  # Idempotent setup — creates tables if they don't exist.
327
327
  # Called automatically on initialize. Safe to call multiple times.
328
328
  def setup!
329
- @pool.with { |conn| conn.exec(MIGRATIONS) }
329
+ with_connection { |conn| conn.exec(MIGRATIONS) }
330
330
  end
331
331
 
332
332
  def close
333
- @pool&.shutdown { |c| c.close }
333
+ @pool&.shutdown { |c| c.close unless c.finished? }
334
334
  end
335
335
 
336
336
  private
337
337
 
338
+ # Check out a connection, running the block with it. A dead
339
+ # pooled connection (the server closed it — a fork inherited it,
340
+ # an idle timeout, a server restart) raises PG::ConnectionBad;
341
+ # reload the pool and retry once so a stale checkout never
342
+ # surfaces to callers.
343
+ def with_connection(&block)
344
+ @pool.with(&block)
345
+ rescue PG::ConnectionBad
346
+ @pool.reload { |conn| conn.close unless conn.finished? }
347
+ @pool.with(&block)
348
+ end
349
+
338
350
  def migrate
339
- @pool.with { |conn| conn.exec(MIGRATIONS) }
351
+ with_connection { |conn| conn.exec(MIGRATIONS) }
340
352
  end
341
353
  end
342
354
  end
@@ -3,7 +3,7 @@
3
3
  module Ask
4
4
  module State
5
5
  module Providers
6
- VERSION = "0.4.5"
6
+ VERSION = "0.4.6"
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-state-providers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto