chat_sdk-state-pg 1.0.0 → 1.1.0

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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chat_sdk/state/pg.rb +64 -0
  3. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5663959fe7eb030f9e94cd6ef2bbfe92d6762e14facbe66fa128f832e372b715
4
- data.tar.gz: 5aa8b46ba8515bc20acaba7d4985534f040e839f04a6d40b12dc6348df26927f
3
+ metadata.gz: dcbe0e018a443c2717ee1e8a5f02941854d14a67cfc5079e4547f50c85392dd7
4
+ data.tar.gz: 1a8a8d102f3a188b28dfeeb4e9474bbdf3e34367585a5c2ba6f817d67c50279a
5
5
  SHA512:
6
- metadata.gz: 11027cec1805e2d7e4f07532842ab2bd234d612e5caf47b1fe7d096f6d8fb28b1ff525a2baca1fd7f1286cd3563fd3b8060e2c6714238a72879231625050f837
7
- data.tar.gz: f3db506a1c1ed0cdb1b2882ee1f80f7af18dd3001b4ec8c4e7e777cbb31d326a7f5672473bd35f8d621b41a3f557396ab123670beb7b7a60e3469df7825d454f
6
+ metadata.gz: ec9ab286bd28012c6a1572c8df4915c160a44b4f08c4cbaa557e59fe4d08b3883f67a4895ec100ad4f58d77ffc40ace6a1e694172ac9d8e8448ea9beb3de635c
7
+ data.tar.gz: 202eb940a1d559384448f75e560c373f37908522c06c32c9e4e18e8b4abf8aec1ad4498c9ef01ef30484348ed960470a53eaace1bb9a0d041c08e00b51a99232
@@ -74,6 +74,15 @@ module ChatSDK
74
74
  true
75
75
  end
76
76
 
77
+ def extend_lock(key, owner:, ttl:)
78
+ result = @conn.exec_params(
79
+ "UPDATE chat_sdk_locks SET expires_at = NOW() + ($4 * INTERVAL '1 second') " \
80
+ "WHERE key_prefix = $1 AND lock_key = $2 AND owner = $3 AND expires_at > NOW()",
81
+ [@key_prefix, key, owner, ttl.to_f]
82
+ )
83
+ result.cmd_tuples > 0
84
+ end
85
+
77
86
  # Key-value store
78
87
 
79
88
  def get(key)
@@ -124,12 +133,56 @@ module ChatSDK
124
133
  result.cmd_tuples > 0
125
134
  end
126
135
 
136
+ def enqueue(key, value, max_size:, drop: :drop_oldest)
137
+ @conn.transaction do |conn|
138
+ conn.exec_params("SELECT pg_advisory_xact_lock(hashtext($1))", ["#{@key_prefix}:#{key}"])
139
+ depth = conn.exec_params(
140
+ "SELECT COUNT(*) AS count FROM chat_sdk_queues WHERE key_prefix = $1 AND queue_key = $2",
141
+ [@key_prefix, key]
142
+ )[0]["count"].to_i
143
+ return depth if depth >= max_size && drop.to_sym == :drop_newest
144
+
145
+ conn.exec_params(
146
+ "INSERT INTO chat_sdk_queues (key_prefix, queue_key, value) VALUES ($1, $2, $3::jsonb)",
147
+ [@key_prefix, key, JSON.generate(value)]
148
+ )
149
+ conn.exec_params(
150
+ "DELETE FROM chat_sdk_queues WHERE id IN (" \
151
+ "SELECT id FROM chat_sdk_queues WHERE key_prefix = $1 AND queue_key = $2 " \
152
+ "ORDER BY id ASC LIMIT (SELECT GREATEST(COUNT(*) - $3, 0) FROM chat_sdk_queues " \
153
+ "WHERE key_prefix = $1 AND queue_key = $2))",
154
+ [@key_prefix, key, max_size]
155
+ )
156
+ [depth + 1, max_size].min
157
+ end
158
+ end
159
+
160
+ def drain_queue(key)
161
+ @conn.transaction do |conn|
162
+ rows = conn.exec_params(
163
+ "DELETE FROM chat_sdk_queues WHERE id IN (" \
164
+ "SELECT id FROM chat_sdk_queues WHERE key_prefix = $1 AND queue_key = $2 ORDER BY id ASC FOR UPDATE) " \
165
+ "RETURNING value, id",
166
+ [@key_prefix, key]
167
+ ).to_a.sort_by { |row| row["id"].to_i }
168
+ rows.map { |row| JSON.parse(row["value"].is_a?(String) ? row["value"] : JSON.generate(row["value"])) }
169
+ end
170
+ end
171
+
172
+ def queue_depth(key)
173
+ @conn.exec_params(
174
+ "SELECT COUNT(*) AS count FROM chat_sdk_queues WHERE key_prefix = $1 AND queue_key = $2",
175
+ [@key_prefix, key]
176
+ )[0]["count"].to_i
177
+ end
178
+
127
179
  # Cleanup
128
180
 
129
181
  def clear
130
182
  @conn.exec_params("DELETE FROM chat_sdk_subscriptions WHERE key_prefix = $1", [@key_prefix])
131
183
  @conn.exec_params("DELETE FROM chat_sdk_locks WHERE key_prefix = $1", [@key_prefix])
132
184
  @conn.exec_params("DELETE FROM chat_sdk_cache WHERE key_prefix = $1", [@key_prefix])
185
+ @conn.exec_params("DELETE FROM chat_sdk_queues WHERE key_prefix = $1", [@key_prefix])
133
186
  end
134
187
 
135
188
  def cleanup_expired
@@ -169,6 +222,17 @@ module ChatSDK
169
222
  expires_at TIMESTAMP,
170
223
  PRIMARY KEY (key_prefix, cache_key)
171
224
  );
225
+
226
+ CREATE TABLE IF NOT EXISTS chat_sdk_queues (
227
+ id BIGSERIAL PRIMARY KEY,
228
+ key_prefix VARCHAR(255) NOT NULL,
229
+ queue_key VARCHAR(512) NOT NULL,
230
+ value JSONB NOT NULL,
231
+ created_at TIMESTAMP DEFAULT NOW()
232
+ );
233
+
234
+ CREATE INDEX IF NOT EXISTS chat_sdk_queues_lookup
235
+ ON chat_sdk_queues (key_prefix, queue_key, id);
172
236
  SQL
173
237
  end
174
238
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chat_sdk-state-pg
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Quentin Rousseau