zizq 0.5.0 → 0.6.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/README.md +4 -3
- data/lib/active_job/queue_adapters/zizq_adapter.rb +42 -20
- data/lib/zizq/ack_processor.rb +17 -11
- data/lib/zizq/active_job_config.rb +30 -10
- data/lib/zizq/backoff.rb +5 -1
- data/lib/zizq/bulk_enqueue.rb +7 -1
- data/lib/zizq/client.rb +288 -185
- data/lib/zizq/configuration.rb +15 -14
- data/lib/zizq/crontab.rb +35 -33
- data/lib/zizq/crontab_builder.rb +1 -7
- data/lib/zizq/crontab_entry.rb +36 -35
- data/lib/zizq/crontab_entry_builder.rb +15 -18
- data/lib/zizq/enqueue_request.rb +51 -38
- data/lib/zizq/enqueue_with.rb +1 -3
- data/lib/zizq/error.rb +12 -6
- data/lib/zizq/job.rb +31 -13
- data/lib/zizq/job_config.rb +217 -13
- data/lib/zizq/lifecycle.rb +10 -2
- data/lib/zizq/middleware.rb +7 -6
- data/lib/zizq/query.rb +85 -67
- data/lib/zizq/resources/cron_entry.rb +7 -7
- data/lib/zizq/resources/cron_group.rb +5 -5
- data/lib/zizq/resources/error_enumerator.rb +11 -9
- data/lib/zizq/resources/error_page.rb +2 -1
- data/lib/zizq/resources/error_record.rb +5 -5
- data/lib/zizq/resources/job.rb +41 -24
- data/lib/zizq/resources/job_page.rb +19 -8
- data/lib/zizq/resources/job_template.rb +16 -8
- data/lib/zizq/resources/page.rb +2 -1
- data/lib/zizq/resources/resource.rb +5 -4
- data/lib/zizq/resources.rb +9 -9
- data/lib/zizq/router.rb +3 -2
- data/lib/zizq/test/client.rb +79 -58
- data/lib/zizq/test.rb +8 -8
- data/lib/zizq/tls_configuration.rb +7 -6
- data/lib/zizq/version.rb +1 -1
- data/lib/zizq/worker.rb +68 -50
- data/lib/zizq/worker_configuration.rb +11 -10
- data/lib/zizq.rb +48 -41
- data/sig/generated/zizq/active_job_config.rbs +16 -5
- data/sig/generated/zizq/bulk_enqueue.rbs +1 -0
- data/sig/generated/zizq/client.rbs +2 -1
- data/sig/generated/zizq/crontab_entry_builder.rbs +1 -0
- data/sig/generated/zizq/enqueue_request.rbs +7 -2
- data/sig/generated/zizq/job.rbs +6 -0
- data/sig/generated/zizq/job_config.rbs +98 -0
- data/sig/generated/zizq/resources/job.rbs +2 -0
- data/sig/generated/zizq/resources/job_template.rbs +5 -2
- data/sig/generated/zizq.rbs +1 -0
- data/sig/zizq.rbs +12 -1
- metadata +2 -2
data/lib/zizq/job_config.rb
CHANGED
|
@@ -49,7 +49,8 @@ module Zizq
|
|
|
49
49
|
#
|
|
50
50
|
# Implemented by the including module.
|
|
51
51
|
def zizq_payload_subset_filter(*args, **kwargs) #: (*untyped, **untyped) -> String
|
|
52
|
-
raise NotImplementedError,
|
|
52
|
+
raise NotImplementedError,
|
|
53
|
+
"#{self} must implement zizq_payload_subset_filter"
|
|
53
54
|
end
|
|
54
55
|
|
|
55
56
|
# Declare the default queue for this job class.
|
|
@@ -116,7 +117,11 @@ module Zizq
|
|
|
116
117
|
raise ArgumentError, "all of exponent:, base:, jitter: are required"
|
|
117
118
|
end
|
|
118
119
|
|
|
119
|
-
@zizq_backoff = {
|
|
120
|
+
@zizq_backoff = {
|
|
121
|
+
exponent: exponent.to_f,
|
|
122
|
+
base: base.to_f,
|
|
123
|
+
jitter: jitter.to_f
|
|
124
|
+
}
|
|
120
125
|
else
|
|
121
126
|
@zizq_backoff
|
|
122
127
|
end
|
|
@@ -170,6 +175,10 @@ module Zizq
|
|
|
170
175
|
if unique.nil?
|
|
171
176
|
@zizq_unique || false
|
|
172
177
|
else
|
|
178
|
+
if unique && zizq_batched
|
|
179
|
+
raise ArgumentError,
|
|
180
|
+
"#{self}: zizq_unique cannot be combined with zizq_batched"
|
|
181
|
+
end
|
|
173
182
|
@zizq_unique = !!unique
|
|
174
183
|
@zizq_unique_scope = scope
|
|
175
184
|
@zizq_unique
|
|
@@ -188,6 +197,105 @@ module Zizq
|
|
|
188
197
|
end
|
|
189
198
|
end
|
|
190
199
|
|
|
200
|
+
# Declare or read batched-job configuration for this class.
|
|
201
|
+
#
|
|
202
|
+
# When enabled, subsequent enqueues that share the batch key are
|
|
203
|
+
# folded into the pending job's payload rather than creating a new
|
|
204
|
+
# job. The batch target is a specific positional arg (`arg:`) or
|
|
205
|
+
# keyword arg (`kwarg:`) whose value must be an array; other args
|
|
206
|
+
# participate in the batch key.
|
|
207
|
+
#
|
|
208
|
+
# zizq_batched true, limit: 100 # arg: 0 by default
|
|
209
|
+
# zizq_batched true, kwarg: :notifications, limit: 100
|
|
210
|
+
# zizq_batched true, limit: 50, dedup: true # + `| unique`
|
|
211
|
+
# zizq_batched true, limit: 50, sorted: true # + `| sort`
|
|
212
|
+
# zizq_batched false # disable in a subclass
|
|
213
|
+
#
|
|
214
|
+
# Cannot be combined with `zizq_unique` — the server rejects the
|
|
215
|
+
# combination and the client raises at declaration time.
|
|
216
|
+
#
|
|
217
|
+
# @rbs enabled: bool?
|
|
218
|
+
# @rbs arg: Integer?
|
|
219
|
+
# @rbs kwarg: Symbol?
|
|
220
|
+
# @rbs limit: Integer?
|
|
221
|
+
# @rbs dedup: bool
|
|
222
|
+
# @rbs sorted: bool
|
|
223
|
+
# @rbs return: bool
|
|
224
|
+
def zizq_batched(
|
|
225
|
+
enabled = nil,
|
|
226
|
+
arg: nil,
|
|
227
|
+
kwarg: nil,
|
|
228
|
+
limit: nil,
|
|
229
|
+
dedup: false,
|
|
230
|
+
sorted: false
|
|
231
|
+
)
|
|
232
|
+
return @zizq_batched || false if enabled.nil?
|
|
233
|
+
|
|
234
|
+
if enabled
|
|
235
|
+
if zizq_unique
|
|
236
|
+
raise ArgumentError,
|
|
237
|
+
"#{self}: zizq_batched cannot be combined with zizq_unique"
|
|
238
|
+
end
|
|
239
|
+
if arg && kwarg
|
|
240
|
+
raise ArgumentError,
|
|
241
|
+
"#{self}: zizq_batched cannot specify both arg: and kwarg:"
|
|
242
|
+
end
|
|
243
|
+
if limit.nil?
|
|
244
|
+
raise ArgumentError, "#{self}: zizq_batched requires limit:"
|
|
245
|
+
end
|
|
246
|
+
unless limit.is_a?(Integer) && limit.positive?
|
|
247
|
+
raise ArgumentError,
|
|
248
|
+
"#{self}: zizq_batched limit: must be a positive Integer"
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
@zizq_batched = true
|
|
252
|
+
@zizq_batch_arg = kwarg.nil? ? (arg || 0) : nil
|
|
253
|
+
@zizq_batch_kwarg = kwarg
|
|
254
|
+
@zizq_batch_limit = limit
|
|
255
|
+
@zizq_batch_dedup = dedup
|
|
256
|
+
@zizq_batch_sorted = sorted
|
|
257
|
+
else
|
|
258
|
+
@zizq_batched = false
|
|
259
|
+
@zizq_batch_arg = nil
|
|
260
|
+
@zizq_batch_kwarg = nil
|
|
261
|
+
@zizq_batch_limit = nil
|
|
262
|
+
@zizq_batch_dedup = false
|
|
263
|
+
@zizq_batch_sorted = false
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
@zizq_batched
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# Positional arg index that participates in the batch payload, or
|
|
270
|
+
# `nil` if `kwarg:` was chosen instead.
|
|
271
|
+
def zizq_batch_arg #: () -> Integer?
|
|
272
|
+
@zizq_batch_arg
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
# Keyword arg name that participates in the batch payload, or `nil`
|
|
276
|
+
# if `arg:` was chosen instead.
|
|
277
|
+
def zizq_batch_kwarg #: () -> Symbol?
|
|
278
|
+
@zizq_batch_kwarg
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# Maximum combined length of the batch payload before the current
|
|
282
|
+
# batch is sealed and a fresh one starts.
|
|
283
|
+
def zizq_batch_limit #: () -> Integer?
|
|
284
|
+
@zizq_batch_limit
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
# Whether the fold expression appends `| unique` to dedup entries
|
|
288
|
+
# within a batch.
|
|
289
|
+
def zizq_batch_dedup? #: () -> bool
|
|
290
|
+
@zizq_batch_dedup || false
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# Whether the fold expression appends `| sort` to sort entries
|
|
294
|
+
# within a batch.
|
|
295
|
+
def zizq_batch_sorted? #: () -> bool
|
|
296
|
+
@zizq_batch_sorted || false
|
|
297
|
+
end
|
|
298
|
+
|
|
191
299
|
# Compute the unique key for a job with the given arguments.
|
|
192
300
|
#
|
|
193
301
|
# The default implementation uses the class name and hashes the
|
|
@@ -198,8 +306,46 @@ module Zizq
|
|
|
198
306
|
# super(user_id) # unique per user, ignoring template
|
|
199
307
|
# end
|
|
200
308
|
def zizq_unique_key(*args, **kwargs) #: (*untyped, **untyped) -> String
|
|
201
|
-
|
|
202
|
-
|
|
309
|
+
hash_args(*args, **kwargs)
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# Compute the batch key for a job with the given arguments.
|
|
313
|
+
#
|
|
314
|
+
# The default implementation drops the configured batch target
|
|
315
|
+
# (positional `arg:` or `kwarg:`) from the arguments and hashes
|
|
316
|
+
# everything else. Two enqueues with the same non-batch arguments
|
|
317
|
+
# therefore produce the same batch key, so they fold into the same
|
|
318
|
+
# pending job; different non-batch arguments produce different keys
|
|
319
|
+
# and end up in separate batches.
|
|
320
|
+
#
|
|
321
|
+
# Override this method to customize batching — for example, to
|
|
322
|
+
# batch by tenant regardless of what else is passed:
|
|
323
|
+
#
|
|
324
|
+
# def self.zizq_batch_key(_notifications, tenant_id:, **_)
|
|
325
|
+
# "#{name}:tenant-#{tenant_id}"
|
|
326
|
+
# end
|
|
327
|
+
def zizq_batch_key(*args, **kwargs) #: (*untyped, **untyped) -> String
|
|
328
|
+
filtered_args =
|
|
329
|
+
args.dup.tap { |a| a.delete_at(zizq_batch_arg) if zizq_batch_arg }
|
|
330
|
+
filtered_kwargs = kwargs.except(zizq_batch_kwarg)
|
|
331
|
+
|
|
332
|
+
hash_args(*filtered_args, **filtered_kwargs)
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
# Build the static jq expressions (`when` predicate, `fold`
|
|
336
|
+
# reducer) for this class's batch configuration.
|
|
337
|
+
#
|
|
338
|
+
# Implemented by the including module — `Zizq::Job` and
|
|
339
|
+
# `Zizq::ActiveJobConfig` know how to target the right JSON path
|
|
340
|
+
# for their respective payload shapes. Returns `nil` when the
|
|
341
|
+
# class is not batched.
|
|
342
|
+
#
|
|
343
|
+
# Override to supply completely custom `when`/`fold` expressions
|
|
344
|
+
# that the DSL flags don't cover.
|
|
345
|
+
def zizq_batch_expressions #: () -> Zizq::batch_expressions?
|
|
346
|
+
return nil unless zizq_batched
|
|
347
|
+
|
|
348
|
+
raise NotImplementedError, "#{self} must implement zizq_batch_expressions"
|
|
203
349
|
end
|
|
204
350
|
|
|
205
351
|
# Build a `Zizq::EnqueueRequest` from the class-level job config.
|
|
@@ -214,26 +360,84 @@ module Zizq
|
|
|
214
360
|
# end
|
|
215
361
|
def zizq_enqueue_request(*args, **kwargs) #: (*untyped, **untyped) -> EnqueueRequest
|
|
216
362
|
EnqueueRequest.new(
|
|
217
|
-
type:
|
|
218
|
-
queue:
|
|
219
|
-
payload:
|
|
220
|
-
priority:
|
|
221
|
-
retry_limit:
|
|
222
|
-
backoff:
|
|
223
|
-
retention:
|
|
363
|
+
type: name || raise(ArgumentError, "Cannot enqueue anonymous class"),
|
|
364
|
+
queue: zizq_queue,
|
|
365
|
+
payload: zizq_serialize(*args, **kwargs),
|
|
366
|
+
priority: zizq_priority,
|
|
367
|
+
retry_limit: zizq_retry_limit,
|
|
368
|
+
backoff: zizq_backoff,
|
|
369
|
+
retention: zizq_retention,
|
|
224
370
|
unique_while: zizq_unique ? zizq_unique_scope : nil,
|
|
225
|
-
unique_key:
|
|
371
|
+
unique_key: zizq_unique ? zizq_unique_key(*args, **kwargs) : nil,
|
|
372
|
+
batch: zizq_batched ? batch_for_enqueue(*args, **kwargs) : nil
|
|
226
373
|
)
|
|
227
374
|
end
|
|
228
375
|
|
|
229
376
|
private
|
|
230
377
|
|
|
378
|
+
# Class-name-prefixed SHA256 of the normalized hashable payload.
|
|
379
|
+
# Shared primitive powering both `zizq_unique_key` and
|
|
380
|
+
# `zizq_batch_key` — the two features hash arguments the same way,
|
|
381
|
+
# they just choose *which* arguments to hash.
|
|
382
|
+
def hash_args(*args, **kwargs) #: (*untyped, **untyped) -> String
|
|
383
|
+
payload = normalize_payload(hashable_args(*args, **kwargs))
|
|
384
|
+
"#{name}:#{Digest::SHA256.hexdigest(JSON.generate(payload))}"
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
# The subset of the serialized payload that participates in key
|
|
388
|
+
# hashing. Defaults to the full serialized payload; overridden by
|
|
389
|
+
# `ActiveJobConfig` to hash only the ActiveJob `arguments` array
|
|
390
|
+
# (skipping volatile envelope fields like `job_id` and
|
|
391
|
+
# `enqueued_at` that vary per enqueue).
|
|
392
|
+
def hashable_args(*args, **kwargs) #: (*untyped, **untyped) -> untyped
|
|
393
|
+
zizq_serialize(*args, **kwargs)
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
# Compose `zizq_batch_expressions` (static) with `zizq_batch_key`
|
|
397
|
+
# (dynamic, arg-dependent) into a full API serialized `Zizq::batch`.
|
|
398
|
+
def batch_for_enqueue(*args, **kwargs) #: (*untyped, **untyped) -> Zizq::batch?
|
|
399
|
+
expr = zizq_batch_expressions
|
|
400
|
+
return nil unless expr
|
|
401
|
+
|
|
402
|
+
{
|
|
403
|
+
key: zizq_batch_key(*args, **kwargs),
|
|
404
|
+
when: expr[:when],
|
|
405
|
+
fold: expr[:fold]
|
|
406
|
+
}
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
# Compile `when`/`fold` expressions targeting a jq path (e.g.
|
|
410
|
+
# `.args[0]` for `Zizq::Job` or `.arguments[-1].notifications`
|
|
411
|
+
# for `ActiveJobConfig`). Applies dedup/sorted flags. Shared
|
|
412
|
+
# across payload shapes because only the target path differs.
|
|
413
|
+
def build_batch_expressions(target) #: (String) -> Zizq::batch_expressions
|
|
414
|
+
limit = zizq_batch_limit
|
|
415
|
+
when_expr = "($existing#{target} + $new#{target}) | length <= #{limit}"
|
|
416
|
+
|
|
417
|
+
fold_expr =
|
|
418
|
+
if zizq_batch_dedup?
|
|
419
|
+
# `unique` in jq also sorts, so it subsumes `sorted:` too.
|
|
420
|
+
"$existing | #{target} = " \
|
|
421
|
+
"(#{target} + $new#{target} | unique)"
|
|
422
|
+
elsif zizq_batch_sorted?
|
|
423
|
+
"$existing | #{target} = " \
|
|
424
|
+
"(#{target} + $new#{target} | sort)"
|
|
425
|
+
else
|
|
426
|
+
"$existing | #{target} += $new#{target}"
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
{ when: when_expr, fold: fold_expr }
|
|
430
|
+
end
|
|
431
|
+
|
|
231
432
|
# Deep-sort all Hash keys so that serialization is deterministic
|
|
232
433
|
# regardless of insertion order or JSON library.
|
|
233
434
|
def normalize_payload(obj) #: (untyped) -> untyped
|
|
234
435
|
case obj
|
|
235
436
|
when Hash
|
|
236
|
-
obj
|
|
437
|
+
obj
|
|
438
|
+
.sort_by { |k, _| k.to_s }
|
|
439
|
+
.map { |k, v| [k, normalize_payload(v)] }
|
|
440
|
+
.to_h
|
|
237
441
|
when Array
|
|
238
442
|
obj.map { |v| normalize_payload(v) }
|
|
239
443
|
else
|
data/lib/zizq/lifecycle.rb
CHANGED
|
@@ -34,7 +34,11 @@ module Zizq
|
|
|
34
34
|
return unless @state == :running
|
|
35
35
|
|
|
36
36
|
@state = :draining
|
|
37
|
-
|
|
37
|
+
begin
|
|
38
|
+
@drain_latch.close
|
|
39
|
+
rescue StandardError
|
|
40
|
+
nil
|
|
41
|
+
end
|
|
38
42
|
end
|
|
39
43
|
|
|
40
44
|
# Transition to :stopped.
|
|
@@ -42,7 +46,11 @@ module Zizq
|
|
|
42
46
|
return if @state == :stopped
|
|
43
47
|
|
|
44
48
|
@state = :stopped
|
|
45
|
-
|
|
49
|
+
begin
|
|
50
|
+
@stop_latch.close
|
|
51
|
+
rescue StandardError
|
|
52
|
+
nil
|
|
53
|
+
end
|
|
46
54
|
end
|
|
47
55
|
|
|
48
56
|
# Block until the state is no longer :running.
|
data/lib/zizq/middleware.rb
CHANGED
|
@@ -52,13 +52,14 @@ module Zizq
|
|
|
52
52
|
private
|
|
53
53
|
|
|
54
54
|
def build #: () -> untyped
|
|
55
|
-
@built ||=
|
|
56
|
-
@
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
@built ||=
|
|
56
|
+
if @entries.empty?
|
|
57
|
+
@terminal
|
|
58
|
+
else
|
|
59
|
+
@entries
|
|
60
|
+
.reverse
|
|
61
|
+
.reduce(@terminal) { |next_link, mw| Link.new(mw, next_link) }
|
|
60
62
|
end
|
|
61
|
-
end
|
|
62
63
|
end
|
|
63
64
|
end
|
|
64
65
|
|
data/lib/zizq/query.rb
CHANGED
|
@@ -62,17 +62,19 @@ module Zizq
|
|
|
62
62
|
# @rbs limit: Integer?
|
|
63
63
|
# @rbs page_size: Integer?
|
|
64
64
|
# @rbs return: void
|
|
65
|
-
def initialize(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
65
|
+
def initialize(
|
|
66
|
+
id: nil,
|
|
67
|
+
queue: nil,
|
|
68
|
+
type: nil,
|
|
69
|
+
status: nil,
|
|
70
|
+
jq_filter: nil,
|
|
71
|
+
priority: nil,
|
|
72
|
+
ready_at: nil,
|
|
73
|
+
attempts: nil,
|
|
74
|
+
order: nil,
|
|
75
|
+
limit: nil,
|
|
76
|
+
page_size: nil
|
|
77
|
+
)
|
|
76
78
|
@id = id
|
|
77
79
|
@queue = queue
|
|
78
80
|
@type = type
|
|
@@ -232,8 +234,11 @@ module Zizq
|
|
|
232
234
|
# @rbs return: Query
|
|
233
235
|
def by_job_class_and_args(job_class, *args, **kwargs)
|
|
234
236
|
validate_job_class!(job_class)
|
|
235
|
-
name = job_class.name or
|
|
236
|
-
|
|
237
|
+
name = job_class.name or
|
|
238
|
+
raise ArgumentError, "anonymous classes are not supported"
|
|
239
|
+
by_type(name).add_jq_filter(
|
|
240
|
+
job_class.zizq_payload_filter(*args, **kwargs)
|
|
241
|
+
)
|
|
237
242
|
end
|
|
238
243
|
|
|
239
244
|
# Filter by job class and a subset of arguments.
|
|
@@ -250,8 +255,11 @@ module Zizq
|
|
|
250
255
|
# @rbs return: Query
|
|
251
256
|
def by_job_class_and_args_subset(job_class, *args, **kwargs)
|
|
252
257
|
validate_job_class!(job_class)
|
|
253
|
-
name = job_class.name or
|
|
254
|
-
|
|
258
|
+
name = job_class.name or
|
|
259
|
+
raise ArgumentError, "anonymous classes are not supported"
|
|
260
|
+
by_type(name).add_jq_filter(
|
|
261
|
+
job_class.zizq_payload_subset_filter(*args, **kwargs)
|
|
262
|
+
)
|
|
255
263
|
end
|
|
256
264
|
|
|
257
265
|
# Replace the jq payload filter expression.
|
|
@@ -363,16 +371,17 @@ module Zizq
|
|
|
363
371
|
def count(*args, &block)
|
|
364
372
|
return super if block || !args.empty?
|
|
365
373
|
|
|
366
|
-
total =
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
374
|
+
total =
|
|
375
|
+
Zizq.client.count_jobs(
|
|
376
|
+
id: @id,
|
|
377
|
+
queue: @queue,
|
|
378
|
+
type: @type,
|
|
379
|
+
status: @status,
|
|
380
|
+
filter: @jq_filter,
|
|
381
|
+
priority: @priority,
|
|
382
|
+
ready_at: @ready_at,
|
|
383
|
+
attempts: @attempts
|
|
384
|
+
)
|
|
376
385
|
|
|
377
386
|
@limit ? [total, @limit].min : total
|
|
378
387
|
end
|
|
@@ -483,18 +492,23 @@ module Zizq
|
|
|
483
492
|
enumerator = enum_for(:each_page)
|
|
484
493
|
|
|
485
494
|
if block_given?
|
|
486
|
-
page =
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
495
|
+
page =
|
|
496
|
+
Zizq.client.list_jobs(
|
|
497
|
+
id: @id,
|
|
498
|
+
queue: @queue,
|
|
499
|
+
type: @type,
|
|
500
|
+
status: @status,
|
|
501
|
+
filter: @jq_filter,
|
|
502
|
+
priority: @priority,
|
|
503
|
+
ready_at: @ready_at,
|
|
504
|
+
attempts: @attempts,
|
|
505
|
+
limit: [
|
|
506
|
+
@page_size,
|
|
507
|
+
@limit,
|
|
508
|
+
(@page_size || @limit) && MAX_PAGE_SIZE
|
|
509
|
+
].compact.min,
|
|
510
|
+
order: @order
|
|
511
|
+
)
|
|
498
512
|
|
|
499
513
|
remaining = @limit
|
|
500
514
|
|
|
@@ -529,12 +543,14 @@ module Zizq
|
|
|
529
543
|
# @rbs backoff: (Zizq::backoff | singleton(Zizq::RESET) | singleton(Zizq::UNCHANGED))?
|
|
530
544
|
# @rbs retention: (Zizq::retention | singleton(Zizq::RESET) | singleton(Zizq::UNCHANGED))?
|
|
531
545
|
# @rbs return: Integer
|
|
532
|
-
def update_all(
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
546
|
+
def update_all(
|
|
547
|
+
queue: Zizq::UNCHANGED,
|
|
548
|
+
priority: Zizq::UNCHANGED,
|
|
549
|
+
ready_at: Zizq::UNCHANGED,
|
|
550
|
+
retry_limit: Zizq::UNCHANGED,
|
|
551
|
+
backoff: Zizq::UNCHANGED,
|
|
552
|
+
retention: Zizq::UNCHANGED
|
|
553
|
+
)
|
|
538
554
|
where = {
|
|
539
555
|
id: @id,
|
|
540
556
|
queue: @queue,
|
|
@@ -543,7 +559,7 @@ module Zizq
|
|
|
543
559
|
filter: @jq_filter,
|
|
544
560
|
priority: @priority,
|
|
545
561
|
ready_at: @ready_at,
|
|
546
|
-
attempts: @attempts
|
|
562
|
+
attempts: @attempts
|
|
547
563
|
}
|
|
548
564
|
|
|
549
565
|
apply = {
|
|
@@ -552,7 +568,7 @@ module Zizq
|
|
|
552
568
|
ready_at:,
|
|
553
569
|
retry_limit:,
|
|
554
570
|
backoff:,
|
|
555
|
-
retention
|
|
571
|
+
retention:
|
|
556
572
|
}
|
|
557
573
|
|
|
558
574
|
if @limit || @page_size
|
|
@@ -567,10 +583,11 @@ module Zizq
|
|
|
567
583
|
ids_on_page = page.jobs.map(&:id)
|
|
568
584
|
ids_on_page = ids_on_page.take(remaining) if remaining
|
|
569
585
|
|
|
570
|
-
updated +=
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
586
|
+
updated +=
|
|
587
|
+
Zizq.client.update_all_jobs(
|
|
588
|
+
where: where.merge(id: ids_on_page),
|
|
589
|
+
apply:
|
|
590
|
+
)
|
|
574
591
|
|
|
575
592
|
remaining -= ids_on_page.size if remaining
|
|
576
593
|
end
|
|
@@ -603,7 +620,7 @@ module Zizq
|
|
|
603
620
|
filter: @jq_filter,
|
|
604
621
|
priority: @priority,
|
|
605
622
|
ready_at: @ready_at,
|
|
606
|
-
attempts: @attempts
|
|
623
|
+
attempts: @attempts
|
|
607
624
|
}
|
|
608
625
|
|
|
609
626
|
if @limit || @page_size
|
|
@@ -618,9 +635,8 @@ module Zizq
|
|
|
618
635
|
ids_on_page = page.jobs.map(&:id)
|
|
619
636
|
ids_on_page = ids_on_page.take(remaining) if remaining
|
|
620
637
|
|
|
621
|
-
deleted +=
|
|
622
|
-
where: where.merge(id: ids_on_page)
|
|
623
|
-
)
|
|
638
|
+
deleted +=
|
|
639
|
+
Zizq.client.delete_all_jobs(where: where.merge(id: ids_on_page))
|
|
624
640
|
|
|
625
641
|
remaining -= ids_on_page.size if remaining
|
|
626
642
|
end
|
|
@@ -636,17 +652,19 @@ module Zizq
|
|
|
636
652
|
# Build a new Query with the given overrides, preserving all other fields.
|
|
637
653
|
#
|
|
638
654
|
# @rbs return: Query
|
|
639
|
-
def rebuild(
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
655
|
+
def rebuild(
|
|
656
|
+
id: @id,
|
|
657
|
+
queue: @queue,
|
|
658
|
+
type: @type,
|
|
659
|
+
status: @status,
|
|
660
|
+
jq_filter: @jq_filter,
|
|
661
|
+
priority: @priority,
|
|
662
|
+
ready_at: @ready_at,
|
|
663
|
+
attempts: @attempts,
|
|
664
|
+
order: @order,
|
|
665
|
+
limit: @limit,
|
|
666
|
+
page_size: @page_size
|
|
667
|
+
)
|
|
650
668
|
self.class.new(
|
|
651
669
|
id:,
|
|
652
670
|
queue:,
|
|
@@ -658,7 +676,7 @@ module Zizq
|
|
|
658
676
|
attempts:,
|
|
659
677
|
limit:,
|
|
660
678
|
order:,
|
|
661
|
-
page_size
|
|
679
|
+
page_size:
|
|
662
680
|
)
|
|
663
681
|
end
|
|
664
682
|
|
|
@@ -667,8 +685,8 @@ module Zizq
|
|
|
667
685
|
def validate_job_class!(job_class)
|
|
668
686
|
unless job_class.is_a?(JobConfig)
|
|
669
687
|
raise ArgumentError,
|
|
670
|
-
|
|
671
|
-
|
|
688
|
+
"#{job_class} does not include Zizq::JobConfig " \
|
|
689
|
+
"(include Zizq::Job or extend Zizq::ActiveJobConfig)"
|
|
672
690
|
end
|
|
673
691
|
end
|
|
674
692
|
end
|
|
@@ -8,13 +8,13 @@ module Zizq
|
|
|
8
8
|
module Resources
|
|
9
9
|
# Typed wrapper around a cron entry response hash.
|
|
10
10
|
class CronEntry < Resource
|
|
11
|
-
def name
|
|
12
|
-
def expression
|
|
13
|
-
def timezone
|
|
14
|
-
def paused
|
|
15
|
-
def paused?
|
|
16
|
-
def paused_at
|
|
17
|
-
def resumed_at
|
|
11
|
+
def name = @data["name"] #: () -> String
|
|
12
|
+
def expression = @data["expression"] #: () -> String
|
|
13
|
+
def timezone = @data["timezone"] #: () -> String?
|
|
14
|
+
def paused = @data["paused"] #: () -> bool
|
|
15
|
+
def paused? = paused #: () -> bool
|
|
16
|
+
def paused_at = ms_to_seconds(@data["paused_at"]) #: () -> Float?
|
|
17
|
+
def resumed_at = ms_to_seconds(@data["resumed_at"]) #: () -> Float?
|
|
18
18
|
def next_enqueue_at = ms_to_seconds(@data["next_enqueue_at"]) #: () -> Float?
|
|
19
19
|
def last_enqueue_at = ms_to_seconds(@data["last_enqueue_at"]) #: () -> Float?
|
|
20
20
|
|
|
@@ -8,11 +8,11 @@ module Zizq
|
|
|
8
8
|
module Resources
|
|
9
9
|
# Typed wrapper around a cron group response hash.
|
|
10
10
|
class CronGroup < Resource
|
|
11
|
-
def name
|
|
12
|
-
def paused
|
|
13
|
-
def paused?
|
|
14
|
-
def paused_at
|
|
15
|
-
def resumed_at
|
|
11
|
+
def name = @data["name"] #: () -> String
|
|
12
|
+
def paused = @data["paused"] #: () -> bool
|
|
13
|
+
def paused? = paused #: () -> bool
|
|
14
|
+
def paused_at = ms_to_seconds(@data["paused_at"]) #: () -> Float?
|
|
15
|
+
def resumed_at = ms_to_seconds(@data["resumed_at"]) #: () -> Float?
|
|
16
16
|
|
|
17
17
|
# Returns the entries in this group as typed resources.
|
|
18
18
|
def entries #: () -> Array[CronEntry]
|
|
@@ -25,10 +25,7 @@ module Zizq
|
|
|
25
25
|
# @rbs limit: Integer?
|
|
26
26
|
# @rbs page_size: Integer?
|
|
27
27
|
# @rbs return: void
|
|
28
|
-
def initialize(id,
|
|
29
|
-
order: nil,
|
|
30
|
-
limit: nil,
|
|
31
|
-
page_size: nil)
|
|
28
|
+
def initialize(id, order: nil, limit: nil, page_size: nil)
|
|
32
29
|
@id = id
|
|
33
30
|
@order = order
|
|
34
31
|
@limit = limit
|
|
@@ -204,11 +201,16 @@ module Zizq
|
|
|
204
201
|
enumerator = enum_for(:each_page)
|
|
205
202
|
|
|
206
203
|
if block_given?
|
|
207
|
-
page =
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
204
|
+
page =
|
|
205
|
+
Zizq.client.list_errors(
|
|
206
|
+
@id,
|
|
207
|
+
limit: [
|
|
208
|
+
@page_size,
|
|
209
|
+
@limit,
|
|
210
|
+
(@page_size || @limit) && MAX_PAGE_SIZE
|
|
211
|
+
].compact.min,
|
|
212
|
+
order: @order
|
|
213
|
+
)
|
|
212
214
|
|
|
213
215
|
remaining = @limit
|
|
214
216
|
|
|
@@ -10,7 +10,8 @@ module Zizq
|
|
|
10
10
|
# @rbs inherits Page[ErrorRecord]
|
|
11
11
|
class ErrorPage < Page
|
|
12
12
|
def items #: () -> Array[ErrorRecord]
|
|
13
|
-
@items ||=
|
|
13
|
+
@items ||=
|
|
14
|
+
(@data["errors"] || []).map { |e| ErrorRecord.new(client, e) }
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
alias errors items
|
|
@@ -8,12 +8,12 @@ module Zizq
|
|
|
8
8
|
module Resources
|
|
9
9
|
# Typed wrapper around a single error record from the job error history.
|
|
10
10
|
class ErrorRecord < Resource
|
|
11
|
-
def attempt
|
|
12
|
-
def message
|
|
13
|
-
def error_type
|
|
14
|
-
def backtrace
|
|
11
|
+
def attempt = @data["attempt"] #: () -> Integer
|
|
12
|
+
def message = @data["message"] #: () -> String
|
|
13
|
+
def error_type = @data["error_type"] #: () -> String?
|
|
14
|
+
def backtrace = @data["backtrace"] #: () -> String?
|
|
15
15
|
def dequeued_at = ms_to_seconds(@data["dequeued_at"]) #: () -> Float
|
|
16
|
-
def failed_at
|
|
16
|
+
def failed_at = ms_to_seconds(@data["failed_at"]) #: () -> Float
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
end
|