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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -3
  3. data/lib/active_job/queue_adapters/zizq_adapter.rb +42 -20
  4. data/lib/zizq/ack_processor.rb +17 -11
  5. data/lib/zizq/active_job_config.rb +30 -10
  6. data/lib/zizq/backoff.rb +5 -1
  7. data/lib/zizq/bulk_enqueue.rb +7 -1
  8. data/lib/zizq/client.rb +288 -185
  9. data/lib/zizq/configuration.rb +15 -14
  10. data/lib/zizq/crontab.rb +35 -33
  11. data/lib/zizq/crontab_builder.rb +1 -7
  12. data/lib/zizq/crontab_entry.rb +36 -35
  13. data/lib/zizq/crontab_entry_builder.rb +15 -18
  14. data/lib/zizq/enqueue_request.rb +51 -38
  15. data/lib/zizq/enqueue_with.rb +1 -3
  16. data/lib/zizq/error.rb +12 -6
  17. data/lib/zizq/job.rb +31 -13
  18. data/lib/zizq/job_config.rb +217 -13
  19. data/lib/zizq/lifecycle.rb +10 -2
  20. data/lib/zizq/middleware.rb +7 -6
  21. data/lib/zizq/query.rb +85 -67
  22. data/lib/zizq/resources/cron_entry.rb +7 -7
  23. data/lib/zizq/resources/cron_group.rb +5 -5
  24. data/lib/zizq/resources/error_enumerator.rb +11 -9
  25. data/lib/zizq/resources/error_page.rb +2 -1
  26. data/lib/zizq/resources/error_record.rb +5 -5
  27. data/lib/zizq/resources/job.rb +41 -24
  28. data/lib/zizq/resources/job_page.rb +19 -8
  29. data/lib/zizq/resources/job_template.rb +16 -8
  30. data/lib/zizq/resources/page.rb +2 -1
  31. data/lib/zizq/resources/resource.rb +5 -4
  32. data/lib/zizq/resources.rb +9 -9
  33. data/lib/zizq/router.rb +3 -2
  34. data/lib/zizq/test/client.rb +79 -58
  35. data/lib/zizq/test.rb +8 -8
  36. data/lib/zizq/tls_configuration.rb +7 -6
  37. data/lib/zizq/version.rb +1 -1
  38. data/lib/zizq/worker.rb +68 -50
  39. data/lib/zizq/worker_configuration.rb +11 -10
  40. data/lib/zizq.rb +48 -41
  41. data/sig/generated/zizq/active_job_config.rbs +16 -5
  42. data/sig/generated/zizq/bulk_enqueue.rbs +1 -0
  43. data/sig/generated/zizq/client.rbs +2 -1
  44. data/sig/generated/zizq/crontab_entry_builder.rbs +1 -0
  45. data/sig/generated/zizq/enqueue_request.rbs +7 -2
  46. data/sig/generated/zizq/job.rbs +6 -0
  47. data/sig/generated/zizq/job_config.rbs +98 -0
  48. data/sig/generated/zizq/resources/job.rbs +2 -0
  49. data/sig/generated/zizq/resources/job_template.rbs +5 -2
  50. data/sig/generated/zizq.rbs +1 -0
  51. data/sig/zizq.rbs +12 -1
  52. metadata +2 -2
@@ -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, "#{self} must implement zizq_payload_subset_filter"
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 = { exponent: exponent.to_f, base: base.to_f, jitter: jitter.to_f }
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
- payload = normalize_payload(zizq_serialize(*args, **kwargs))
202
- "#{name}:#{Digest::SHA256.hexdigest(JSON.generate(payload))}"
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: name || raise(ArgumentError, "Cannot enqueue anonymous class"),
218
- queue: zizq_queue,
219
- payload: zizq_serialize(*args, **kwargs),
220
- priority: zizq_priority,
221
- retry_limit: zizq_retry_limit,
222
- backoff: zizq_backoff,
223
- retention: zizq_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: zizq_unique ? zizq_unique_key(*args, **kwargs) : nil
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.sort_by { |k, _| k.to_s }.map { |k, v| [k, normalize_payload(v)] }.to_h
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
@@ -34,7 +34,11 @@ module Zizq
34
34
  return unless @state == :running
35
35
 
36
36
  @state = :draining
37
- @drain_latch.close rescue nil
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
- @stop_latch.close rescue nil
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.
@@ -52,13 +52,14 @@ module Zizq
52
52
  private
53
53
 
54
54
  def build #: () -> untyped
55
- @built ||= if @entries.empty?
56
- @terminal
57
- else
58
- @entries.reverse.reduce(@terminal) do |next_link, mw|
59
- Link.new(mw, next_link)
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(id: nil,
66
- queue: nil,
67
- type: nil,
68
- status: nil,
69
- jq_filter: nil,
70
- priority: nil,
71
- ready_at: nil,
72
- attempts: nil,
73
- order: nil,
74
- limit: nil,
75
- page_size: nil)
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 raise ArgumentError, "anonymous classes are not supported"
236
- by_type(name).add_jq_filter(job_class.zizq_payload_filter(*args, **kwargs))
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 raise ArgumentError, "anonymous classes are not supported"
254
- by_type(name).add_jq_filter(job_class.zizq_payload_subset_filter(*args, **kwargs))
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 = Zizq.client.count_jobs(
367
- id: @id,
368
- queue: @queue,
369
- type: @type,
370
- status: @status,
371
- filter: @jq_filter,
372
- priority: @priority,
373
- ready_at: @ready_at,
374
- attempts: @attempts,
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 = Zizq.client.list_jobs(
487
- id: @id,
488
- queue: @queue,
489
- type: @type,
490
- status: @status,
491
- filter: @jq_filter,
492
- priority: @priority,
493
- ready_at: @ready_at,
494
- attempts: @attempts,
495
- limit: [@page_size, @limit, (@page_size || @limit) && MAX_PAGE_SIZE].compact.min,
496
- order: @order,
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(queue: Zizq::UNCHANGED,
533
- priority: Zizq::UNCHANGED,
534
- ready_at: Zizq::UNCHANGED,
535
- retry_limit: Zizq::UNCHANGED,
536
- backoff: Zizq::UNCHANGED,
537
- retention: Zizq::UNCHANGED)
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 += Zizq.client.update_all_jobs(
571
- where: where.merge(id: ids_on_page),
572
- apply:,
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 += Zizq.client.delete_all_jobs(
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(id: @id,
640
- queue: @queue,
641
- type: @type,
642
- status: @status,
643
- jq_filter: @jq_filter,
644
- priority: @priority,
645
- ready_at: @ready_at,
646
- attempts: @attempts,
647
- order: @order,
648
- limit: @limit,
649
- page_size: @page_size)
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
- "#{job_class} does not include Zizq::JobConfig " \
671
- "(include Zizq::Job or extend Zizq::ActiveJobConfig)"
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 = @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?
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 = @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?
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 = Zizq.client.list_errors(
208
- @id,
209
- limit: [@page_size, @limit, (@page_size || @limit) && MAX_PAGE_SIZE].compact.min,
210
- order: @order,
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 ||= (@data["errors"] || []).map { |e| ErrorRecord.new(client, e) }
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 = @data["attempt"] #: () -> Integer
12
- def message = @data["message"] #: () -> String
13
- def error_type = @data["error_type"] #: () -> String?
14
- def backtrace = @data["backtrace"] #: () -> String?
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 = ms_to_seconds(@data["failed_at"]) #: () -> Float
16
+ def failed_at = ms_to_seconds(@data["failed_at"]) #: () -> Float
17
17
  end
18
18
  end
19
19
  end