ask-state-providers 0.4.3 → 0.4.4
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/lib/ask/state/providers/postgres.rb +22 -10
- data/lib/ask/state/providers/version.rb +1 -1
- metadata +29 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 269e8a62defb31a02eb53fe42e5e13fb375b1a2037d3feb1a88048481f670ff5
|
|
4
|
+
data.tar.gz: 86ca88be92adcd9ee95651904cf3fd72079a1adc899a1870c87065de1657d1e8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0f8cd296decf02725687d44a96d3991b074fe975425885bf49ca064f68472370ed17d4596a336c8abaf6f8ff20366d0d7ff571a26dd7f46df1a0017c1d5053ac
|
|
7
|
+
data.tar.gz: 7c7425f0732e1f92b66b9458274ded4009e42ef673ac354e266290055af0792a0451d27e2c1b6b1ff9329c26ed2e0400283471dd4890962a7b7b8c1dfae75cd1
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
require "json"
|
|
4
4
|
require "time"
|
|
5
5
|
require "securerandom"
|
|
6
|
+
require "connection_pool"
|
|
7
|
+
require "pg"
|
|
6
8
|
|
|
7
9
|
module Ask
|
|
8
10
|
module State
|
|
@@ -58,8 +60,6 @@ module Ask
|
|
|
58
60
|
# @param pool_size [Integer] connection pool size (default 5)
|
|
59
61
|
def initialize(url: ENV.fetch("DATABASE_URL", "postgres://localhost:5432/ask_state"),
|
|
60
62
|
pool_size: 5)
|
|
61
|
-
require "pg"
|
|
62
|
-
|
|
63
63
|
@pool = ConnectionPool.new(size: pool_size) do
|
|
64
64
|
::PG.connect(url)
|
|
65
65
|
end
|
|
@@ -81,9 +81,11 @@ module Ask
|
|
|
81
81
|
|
|
82
82
|
def set(key, value, ttl: nil)
|
|
83
83
|
@pool.with do |conn|
|
|
84
|
+
# Explicit casts: $3 is nil when no ttl, and PostgreSQL can't
|
|
85
|
+
# infer a type for a bare NULL parameter.
|
|
84
86
|
conn.exec_params(<<~SQL, [key, JSON.generate(value), ttl ? Time.now.utc + ttl : nil])
|
|
85
87
|
INSERT INTO state_store (key, value, expires_at)
|
|
86
|
-
VALUES ($1, $2, $3)
|
|
88
|
+
VALUES ($1::text, $2::text, $3::timestamptz)
|
|
87
89
|
ON CONFLICT (key) DO UPDATE SET
|
|
88
90
|
value = EXCLUDED.value,
|
|
89
91
|
expires_at = EXCLUDED.expires_at
|
|
@@ -105,14 +107,21 @@ module Ask
|
|
|
105
107
|
now = Time.now.utc
|
|
106
108
|
expires = ttl ? now + ttl : nil
|
|
107
109
|
|
|
110
|
+
# Insert when the key is missing or its row is expired. An
|
|
111
|
+
# expired row still conflicts on the primary key, so the
|
|
112
|
+
# ON CONFLICT branch overwrites it — but only when it is
|
|
113
|
+
# actually expired, never a live value.
|
|
108
114
|
result = conn.exec_params(<<~SQL, [key, JSON.generate(value), expires, now])
|
|
109
115
|
INSERT INTO state_store (key, value, expires_at)
|
|
110
|
-
SELECT $1, $2, $3
|
|
116
|
+
SELECT $1::text, $2::text, $3::timestamptz
|
|
111
117
|
WHERE NOT EXISTS (
|
|
112
118
|
SELECT 1 FROM state_store
|
|
113
119
|
WHERE key = $1 AND (expires_at IS NULL OR expires_at > $4)
|
|
114
120
|
)
|
|
115
|
-
ON CONFLICT (key) DO
|
|
121
|
+
ON CONFLICT (key) DO UPDATE SET
|
|
122
|
+
value = EXCLUDED.value,
|
|
123
|
+
expires_at = EXCLUDED.expires_at
|
|
124
|
+
WHERE state_store.expires_at IS NOT NULL AND state_store.expires_at <= $4
|
|
116
125
|
SQL
|
|
117
126
|
result.cmd_tuples > 0
|
|
118
127
|
end
|
|
@@ -167,9 +176,9 @@ module Ask
|
|
|
167
176
|
conn.exec_params("DELETE FROM locks WHERE key = $1 AND expires_at <= $2",
|
|
168
177
|
[key, now])
|
|
169
178
|
|
|
170
|
-
result = conn.exec_params(<<~SQL, [key, expires_at_time, token
|
|
179
|
+
result = conn.exec_params(<<~SQL, [key, expires_at_time, token])
|
|
171
180
|
INSERT INTO locks (key, expires_at, token)
|
|
172
|
-
SELECT $1, $2, $3
|
|
181
|
+
SELECT $1::text, $2::timestamptz, $3::text
|
|
173
182
|
WHERE NOT EXISTS (
|
|
174
183
|
SELECT 1 FROM locks
|
|
175
184
|
WHERE key = $1
|
|
@@ -248,13 +257,16 @@ module Ask
|
|
|
248
257
|
|
|
249
258
|
return unless max_length
|
|
250
259
|
|
|
251
|
-
|
|
252
|
-
|
|
260
|
+
# Keep the newest max_length entries: the cutoff is the
|
|
261
|
+
# oldest id inside the newest max_length — delete strictly
|
|
262
|
+
# older rows (and only this list's).
|
|
263
|
+
conn.exec_params(<<~SQL, [key, max_length, key])
|
|
264
|
+
DELETE FROM lists WHERE list_key = $3 AND id < (
|
|
253
265
|
SELECT COALESCE(MIN(id), 0) FROM (
|
|
254
266
|
SELECT id FROM lists
|
|
255
267
|
WHERE list_key = $1
|
|
256
268
|
ORDER BY id DESC
|
|
257
|
-
LIMIT $
|
|
269
|
+
LIMIT $2::bigint
|
|
258
270
|
) sub
|
|
259
271
|
)
|
|
260
272
|
SQL
|
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.
|
|
4
|
+
version: 0.4.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kaka Ruto
|
|
@@ -23,6 +23,34 @@ dependencies:
|
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: 0.11.3
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: connection_pool
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '2.2'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '2.2'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: pg
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '1.5'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.5'
|
|
26
54
|
- !ruby/object:Gem::Dependency
|
|
27
55
|
name: minitest
|
|
28
56
|
requirement: !ruby/object:Gem::Requirement
|