riverqueue-activerecord 0.15.0 → 0.16.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.
- checksums.yaml +4 -4
- data/lib/driver.rb +93 -86
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 52855b59287d8ff3cfac156f94aef4bf887344c52461de4935c90e8e173eebdf
|
|
4
|
+
data.tar.gz: f0433acb86e87f358fdde11c125f595dc6a8a09ff1dd56b7cd7b34c516dabe1f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c6dcc04e8179b62aaedd0630a7b222f048578a02a089e087b10f38f089c0e14b87358ba589188c89aff167a48d419998f57e599ded18381c1ff8c44ca328a800
|
|
7
|
+
data.tar.gz: dfe8e481b770a80fb8e779536b60779f95dbe40f3a9001e36a3e1be44ce4ce63e8531bc411e49dc291b4a7e196fb4ca66da50d9c86e5443e76b7fcac0d01d051
|
data/lib/driver.rb
CHANGED
|
@@ -31,7 +31,7 @@ module River::Driver
|
|
|
31
31
|
|
|
32
32
|
@connection_class = connection_class
|
|
33
33
|
@postgres_capabilities_cache = PostgresCapabilities::Cache.new
|
|
34
|
-
@is_sqlite = connection_class.connection.adapter_name.downcase.include?("sqlite")
|
|
34
|
+
@is_sqlite = connection_class.connection_pool.with_connection { |connection| connection.adapter_name.downcase.include?("sqlite") }
|
|
35
35
|
# Do not inherit application scopes, callbacks, or schema caches. Each
|
|
36
36
|
# driver owns its model, but all operations use the selected class's pool.
|
|
37
37
|
@job_model = Class.new(::ActiveRecord::Base) do
|
|
@@ -59,13 +59,7 @@ module River::Driver
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def job_get_by_id(id)
|
|
62
|
-
|
|
63
|
-
row = sqlite_job_rows("WHERE id = ? LIMIT 1", [id]).first
|
|
64
|
-
row ? sqlite_to_job_row_from_raw(row) : nil
|
|
65
|
-
else
|
|
66
|
-
row = @job_model.find_by(id: id)
|
|
67
|
-
row ? to_job_row_from_model(row) : nil
|
|
68
|
-
end
|
|
62
|
+
runtime_query_jobs("SELECT #{runtime_job_columns} FROM river_job WHERE id = #{Integer(id)} LIMIT 1").first
|
|
69
63
|
end
|
|
70
64
|
|
|
71
65
|
def job_insert(insert_params)
|
|
@@ -75,12 +69,14 @@ module River::Driver
|
|
|
75
69
|
def job_insert_many(insert_params_many)
|
|
76
70
|
return [] if insert_params_many.empty?
|
|
77
71
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
72
|
+
runtime_insert_transaction(insert_params_many) do
|
|
73
|
+
if @is_sqlite
|
|
74
|
+
sqlite_job_insert_many(insert_params_many)
|
|
75
|
+
else
|
|
76
|
+
results = postgres_job_insert_many(insert_params_many)
|
|
77
|
+
postgres_notify_insert(insert_params_many)
|
|
78
|
+
results
|
|
79
|
+
end
|
|
84
80
|
end
|
|
85
81
|
end
|
|
86
82
|
|
|
@@ -114,13 +110,14 @@ module River::Driver
|
|
|
114
110
|
# result. Joins an open, joinable transaction instead of opening a
|
|
115
111
|
# savepoint.
|
|
116
112
|
def transaction(&)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
113
|
+
@connection_class.connection_pool.with_connection do |connection|
|
|
114
|
+
legacy = runtime_legacy_subtransactions?
|
|
115
|
+
# A joined Active Record block swallows ActiveRecord::Rollback without
|
|
116
|
+
# rolling anything back. Let the transaction's owner receive it.
|
|
117
|
+
next yield if !legacy && connection.current_transaction.joinable?
|
|
122
118
|
|
|
123
|
-
|
|
119
|
+
connection.transaction(requires_new: legacy, &)
|
|
120
|
+
end
|
|
124
121
|
end
|
|
125
122
|
|
|
126
123
|
SQLITE_CONFLICT_WHERE = <<~SQL.chomp.freeze
|
|
@@ -245,7 +242,11 @@ module River::Driver
|
|
|
245
242
|
end
|
|
246
243
|
|
|
247
244
|
private def runtime_execute(sql)
|
|
248
|
-
@connection_class.connection.execute(sql)
|
|
245
|
+
@connection_class.connection_pool.with_connection { |connection| connection.execute(sql) }
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
private def runtime_job_columns
|
|
249
|
+
@is_sqlite ? SQLITE_JOB_COLUMNS : "*"
|
|
249
250
|
end
|
|
250
251
|
|
|
251
252
|
private def runtime_job_list_without_params
|
|
@@ -253,11 +254,7 @@ module River::Driver
|
|
|
253
254
|
end
|
|
254
255
|
|
|
255
256
|
private def runtime_job_rows(suffix)
|
|
256
|
-
|
|
257
|
-
sqlite_job_rows(suffix).map { |row| sqlite_to_job_row_from_raw(row) }
|
|
258
|
-
else
|
|
259
|
-
@job_model.find_by_sql("SELECT * FROM river_job #{suffix}").map { |row| to_job_row_from_model(row) }
|
|
260
|
-
end
|
|
257
|
+
runtime_query_jobs("SELECT #{runtime_job_columns} FROM river_job #{suffix}")
|
|
261
258
|
end
|
|
262
259
|
|
|
263
260
|
private def runtime_notification_connection
|
|
@@ -274,15 +271,25 @@ module River::Driver
|
|
|
274
271
|
end
|
|
275
272
|
|
|
276
273
|
private def runtime_query_rows(sql)
|
|
277
|
-
|
|
278
|
-
@
|
|
279
|
-
|
|
280
|
-
|
|
274
|
+
@connection_class.connection_pool.with_connection do |connection|
|
|
275
|
+
if @is_sqlite
|
|
276
|
+
connection.raw_connection.execute(sql).to_a
|
|
277
|
+
else
|
|
278
|
+
# exec_query invalidates the query cache for writes with RETURNING.
|
|
279
|
+
# Deserialize without allocating an Active Record model per job.
|
|
280
|
+
result = connection.exec_query(sql)
|
|
281
|
+
types = result.column_types
|
|
282
|
+
result.rows.map do |row|
|
|
283
|
+
result.columns.each_with_index.to_h do |column, index|
|
|
284
|
+
[column, types.fetch(index).deserialize(row[index])]
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
end
|
|
281
288
|
end
|
|
282
289
|
end
|
|
283
290
|
|
|
284
291
|
private def runtime_quote(value)
|
|
285
|
-
@connection_class.connection.quote(value)
|
|
292
|
+
@connection_class.connection_pool.with_connection { |connection| connection.quote(value) }
|
|
286
293
|
end
|
|
287
294
|
|
|
288
295
|
private def runtime_value(row, key)
|
|
@@ -313,61 +320,59 @@ module River::Driver
|
|
|
313
320
|
# matching migration 007 and newer River databases.
|
|
314
321
|
private def sqlite_job_insert_many(insert_params_many)
|
|
315
322
|
nonces = sqlite_insert_nonces(insert_params_many)
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
SQL
|
|
323
|
+
jobs = insert_params_many.zip(nonces).map { |param, nonce| sqlite_insert_params_to_hash(param, nonce) }
|
|
324
|
+
inserted_nonces = nonces.to_h { |nonce| [nonce, true] }
|
|
325
|
+
|
|
326
|
+
sql = <<~SQL
|
|
327
|
+
INSERT INTO river_job (
|
|
328
|
+
args,
|
|
329
|
+
created_at,
|
|
330
|
+
kind,
|
|
331
|
+
max_attempts,
|
|
332
|
+
metadata,
|
|
333
|
+
priority,
|
|
334
|
+
queue,
|
|
335
|
+
scheduled_at,
|
|
336
|
+
state,
|
|
337
|
+
tags,
|
|
338
|
+
unique_key,
|
|
339
|
+
unique_states
|
|
340
|
+
)
|
|
341
|
+
SELECT
|
|
342
|
+
jsonb(json_extract(value, '$.args')),
|
|
343
|
+
datetime('now', 'subsec'),
|
|
344
|
+
cast(json_extract(value, '$.kind') AS text),
|
|
345
|
+
cast(json_extract(value, '$.max_attempts') AS integer),
|
|
346
|
+
jsonb(json_extract(value, '$.metadata')),
|
|
347
|
+
cast(json_extract(value, '$.priority') AS integer),
|
|
348
|
+
cast(json_extract(value, '$.queue') AS text),
|
|
349
|
+
coalesce(cast(json_extract(value, '$.scheduled_at') AS text), datetime('now', 'subsec')),
|
|
350
|
+
cast(json_extract(value, '$.state') AS text),
|
|
351
|
+
jsonb(json_extract(value, '$.tags')),
|
|
352
|
+
CASE
|
|
353
|
+
WHEN length(cast(json_extract(value, '$.unique_key') AS text)) = 0 THEN NULL
|
|
354
|
+
ELSE unhex(cast(json_extract(value, '$.unique_key') AS text))
|
|
355
|
+
END,
|
|
356
|
+
nullif(cast(json_extract(value, '$.unique_states') AS integer), 0)
|
|
357
|
+
FROM json_each(cast(? AS blob))
|
|
358
|
+
WHERE true
|
|
359
|
+
ON CONFLICT (unique_key) WHERE #{SQLITE_CONFLICT_WHERE}
|
|
360
|
+
DO UPDATE SET kind = river_job.kind
|
|
361
|
+
RETURNING #{SQLITE_JOB_COLUMNS}
|
|
362
|
+
SQL
|
|
357
363
|
|
|
358
|
-
|
|
359
|
-
|
|
364
|
+
rows = @connection_class.connection_pool.with_connection { |connection| connection.raw_connection.execute(sql, [JSON.generate(jobs)]) }
|
|
365
|
+
sqlite_notify_insert(insert_params_many)
|
|
360
366
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
end
|
|
367
|
+
rows.map do |row|
|
|
368
|
+
job = sqlite_to_job_row_from_raw(row)
|
|
369
|
+
[job, !inserted_nonces.key?(job.metadata[UNIQUE_INSERT_METADATA_KEY])]
|
|
365
370
|
end
|
|
366
371
|
end
|
|
367
372
|
|
|
368
373
|
private def sqlite_job_rows(suffix, binds = [])
|
|
369
374
|
sql = "SELECT #{SQLITE_JOB_COLUMNS} FROM river_job #{suffix}"
|
|
370
|
-
@connection_class.connection.raw_connection.execute(sql, binds)
|
|
375
|
+
@connection_class.connection_pool.with_connection { |connection| connection.raw_connection.execute(sql, binds) }
|
|
371
376
|
end
|
|
372
377
|
|
|
373
378
|
private def sqlite_notify_insert(insert_params_many)
|
|
@@ -381,13 +386,15 @@ module River::Driver
|
|
|
381
386
|
{payload: JSON.generate({queue: queue}), topic: "river_insert"}
|
|
382
387
|
end
|
|
383
388
|
|
|
384
|
-
@connection_class.
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
389
|
+
@connection_class.connection_pool.with_connection do |connection|
|
|
390
|
+
connection.raw_connection.execute(<<~SQL, [JSON.generate(notifications)])
|
|
391
|
+
INSERT INTO river_notification (payload, topic)
|
|
392
|
+
SELECT
|
|
393
|
+
json_extract(value, '$.payload'),
|
|
394
|
+
json_extract(value, '$.topic')
|
|
395
|
+
FROM json_each(cast(? AS blob))
|
|
396
|
+
SQL
|
|
397
|
+
end
|
|
391
398
|
end
|
|
392
399
|
|
|
393
400
|
private def sqlite_to_job_row_from_model(river_job)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: riverqueue-activerecord
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.16.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Blake Gentry
|
|
@@ -56,14 +56,14 @@ dependencies:
|
|
|
56
56
|
requirements:
|
|
57
57
|
- - '='
|
|
58
58
|
- !ruby/object:Gem::Version
|
|
59
|
-
version: 0.
|
|
59
|
+
version: 0.16.0
|
|
60
60
|
type: :runtime
|
|
61
61
|
prerelease: false
|
|
62
62
|
version_requirements: !ruby/object:Gem::Requirement
|
|
63
63
|
requirements:
|
|
64
64
|
- - '='
|
|
65
65
|
- !ruby/object:Gem::Version
|
|
66
|
-
version: 0.
|
|
66
|
+
version: 0.16.0
|
|
67
67
|
description: ActiveRecord Postgres and SQLite driver for inserting and working River
|
|
68
68
|
jobs in Ruby.
|
|
69
69
|
email: brandur@brandur.org
|