zizq 0.2.0 → 0.2.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb5651af26b76aeb9da0d00636cb1c2f10479c544c52083d16436f46670ba346
4
- data.tar.gz: 30b0a1142d96c565d11ef4252f07305e6ef55ac264217a8540975236ae007958
3
+ metadata.gz: de36f4f8204a5d5b0c64e77b78249ed34ea6c667ceb6b03dbdca2a291cb0f330
4
+ data.tar.gz: 7cbb62aac1788627bb1047b474e5ca915c5dca059bc6f00be7a2f5adca798a7a
5
5
  SHA512:
6
- metadata.gz: 73d90b0c47f1dcf3452d573829211d69f853b38aca8d0b7e14be74017ac9b802f3faa9151f11ae1fcc0644a574d0b91dc308eec7c8fd560dccf93e1ab31ef321
7
- data.tar.gz: '0843a45519c6d0c6256450e242887a08489fdfb84040f6f302ba615118e5dfb9171cc52db1e5407446d0caa4012ff3b136a583f421c19ea3cd0fe6ba92a38371'
6
+ metadata.gz: 95b80cec6e0bb1704bd1244b37c4434b5d5467139e35c61bae39f342825a3e136a413aa55c0a0b7de379024bcdee3486e08cb211062a9d406011093a68de2899
7
+ data.tar.gz: '09952b2563e139e9987473b53524ea993f1c803ea0320082c166132053919f3401cad65c8dc063923837c3b1fe8a505e3e27dcd9ce6a20724313c1d6f82c00e3'
@@ -9,8 +9,9 @@ require_relative "job_config"
9
9
  module Zizq
10
10
  # Zizq configuration DSL for ActiveJob classes.
11
11
  #
12
- # Extend this module in an ActiveJob subclass to gain access to Zizq
13
- # features like unique jobs, backoff, and retention:
12
+ # Extend this module in an ActiveJob subclass to allow enqueueing jobs via
13
+ # `Zizq.enqueue` and to gain access to Zizq features like unique jobs,
14
+ # backoff, and retention:
14
15
  #
15
16
  # class SendEmailJob < ApplicationJob
16
17
  # extend Zizq::ActiveJobConfig
@@ -36,17 +37,28 @@ module Zizq
36
37
  # @rbs!
37
38
  # # ActiveJob::Base.new — invisible to steep without this.
38
39
  # def new: (*untyped, **untyped) -> untyped
40
+ #
41
+ # # ActiveJob::Base.queue_name — invisible to steep without this.
42
+ # def queue_name: () -> String?
43
+
44
+ # Use ActiveJob's `queue_name` as the default queue, falling back to
45
+ # any explicit `zizq_queue` setting, then "default".
46
+ def zizq_queue(name = nil) #: (?String?) -> String
47
+ if name
48
+ super
49
+ else
50
+ @zizq_queue || queue_name || "default"
51
+ end
52
+ end
39
53
 
40
- # Serialize arguments using ActiveJob's serialization format.
54
+ # Serialize using ActiveJob's own format.
41
55
  #
42
56
  # Creates a temporary ActiveJob instance to produce the canonical
43
- # serialized form, including `_aj_ruby2_keywords` markers for kwargs.
44
- # This ensures unique key generation uses the same format as the
45
- # enqueued payload.
46
- #
47
- # This is needed so that unique job keys can be correctly generated.
48
- def zizq_serialize(*args, **kwargs) #: (*untyped, **untyped) -> Array[untyped]
49
- new(*args, **kwargs).serialize["arguments"]
57
+ # serialized form. Returns the full serialized hash (including
58
+ # `job_class`, `arguments`, `queue_name`, etc.) so that the payload
59
+ # stored in Zizq matches what `ActiveJob::Base.execute` expects.
60
+ def zizq_serialize(*args, **kwargs) #: (*untyped, **untyped) -> Hash[String, untyped]
61
+ new(*args, **kwargs).serialize
50
62
  end
51
63
 
52
64
  # Deserialization is handled by ActiveJob::Base.execute on the worker
@@ -56,6 +68,15 @@ module Zizq
56
68
  "ActiveJob handles deserialization via ActiveJob::Base.execute"
57
69
  end
58
70
 
71
+ # Override unique key generation to hash only the arguments portion
72
+ # of the serialized payload. The full payload contains volatile fields
73
+ # (job_id, enqueued_at, etc.) that change per instance.
74
+ def zizq_unique_key(*args, **kwargs) #: (*untyped, **untyped) -> String
75
+ arguments = new(*args, **kwargs).serialize["arguments"]
76
+ payload = normalize_payload(arguments)
77
+ "#{name}:#{Digest::SHA256.hexdigest(JSON.generate(payload))}"
78
+ end
79
+
59
80
  # Generate a jq expression that exactly matches payloads with the given
60
81
  # arguments.
61
82
  #
@@ -65,8 +86,8 @@ module Zizq
65
86
  #
66
87
  # .arguments == ["a","b",{"example":true,"_aj_ruby2_keywords":["example"]}]
67
88
  def zizq_payload_filter(*args, **kwargs) #: (*untyped, **untyped) -> String
68
- payload = zizq_serialize(*args, **kwargs)
69
- ".arguments == #{JSON.generate(payload)}"
89
+ arguments = zizq_serialize(*args, **kwargs)["arguments"]
90
+ ".arguments == #{JSON.generate(arguments)}"
70
91
  end
71
92
 
72
93
  # Generate a jq expression that matches jobs whose positional args
@@ -85,27 +106,27 @@ module Zizq
85
106
  # (.arguments[-1] | has("_aj_ruby2_keywords")) and
86
107
  # (.arguments[-1] | contains({"example":true}))
87
108
  def zizq_payload_subset_filter(*args, **kwargs) #: (*untyped, **untyped) -> String
88
- payload = zizq_serialize(*args, **kwargs)
109
+ arguments = zizq_serialize(*args, **kwargs)["arguments"]
89
110
 
90
111
  # ActiveJob flattens arguments into a single array, but marks kwargs with
91
112
  # "_aj_ruby2_keywords" => ["key1", "key2", ...] in the last element of
92
113
  # the array where kwargs are present. We need to detect this to generate
93
114
  # a suitable expression.
94
115
  serialized_args, serialized_kwargs =
95
- if payload.size > 0
116
+ if arguments.size > 0
96
117
  # See what the last argument looks like. It might be kwargs.
97
- maybe_kwargs = payload.pop
118
+ maybe_kwargs = arguments.pop
98
119
 
99
120
  # If it's got "_aj_ruby2_keywords" then it is kwargs.
100
121
  if maybe_kwargs.is_a?(Hash) && maybe_kwargs["_aj_ruby2_keywords"]
101
122
  # We only want the actual kwargs, not the marker.
102
- [payload, maybe_kwargs.except("_aj_ruby2_keywords")]
123
+ [arguments, maybe_kwargs.except("_aj_ruby2_keywords")]
103
124
  else
104
125
  # It wasn't kwargs, so put it back.
105
- [payload.push(maybe_kwargs), nil]
126
+ [arguments.push(maybe_kwargs), nil]
106
127
  end
107
128
  else
108
- [payload, nil]
129
+ [arguments, nil]
109
130
  end
110
131
 
111
132
  parts = [] #: Array[String]
data/lib/zizq/version.rb CHANGED
@@ -5,5 +5,5 @@
5
5
  # frozen_string_literal: true
6
6
 
7
7
  module Zizq
8
- VERSION = "0.2.0" #: String
8
+ VERSION = "0.2.1" #: String
9
9
  end
data/lib/zizq.rb CHANGED
@@ -253,8 +253,8 @@ module Zizq
253
253
  # @rbs &block: ?(EnqueueRequest) -> void
254
254
  # @rbs return: EnqueueRequest
255
255
  def build_enqueue_request(job_class, *args, **kwargs, &block)
256
- unless job_class.is_a?(Class) && job_class < Zizq::Job
257
- raise ArgumentError, "#{job_class.inspect} must include Zizq::Job"
256
+ unless job_class.is_a?(Class) && job_class.is_a?(Zizq::JobConfig)
257
+ raise ArgumentError, "#{job_class.inspect} must include Zizq::Job or extend Zizq::ActiveJobConfig"
258
258
  end
259
259
 
260
260
  zizq_job_class = job_class #: Zizq::job_class
@@ -3,8 +3,9 @@
3
3
  module Zizq
4
4
  # Zizq configuration DSL for ActiveJob classes.
5
5
  #
6
- # Extend this module in an ActiveJob subclass to gain access to Zizq
7
- # features like unique jobs, backoff, and retention:
6
+ # Extend this module in an ActiveJob subclass to allow enqueueing jobs via
7
+ # `Zizq.enqueue` and to gain access to Zizq features like unique jobs,
8
+ # backoff, and retention:
8
9
  #
9
10
  # class SendEmailJob < ApplicationJob
10
11
  # extend Zizq::ActiveJobConfig
@@ -30,20 +31,30 @@ module Zizq
30
31
  # ActiveJob::Base.new — invisible to steep without this.
31
32
  def new: (*untyped, **untyped) -> untyped
32
33
 
33
- # Serialize arguments using ActiveJob's serialization format.
34
+ # ActiveJob::Base.queue_name invisible to steep without this.
35
+ def queue_name: () -> String?
36
+
37
+ # Use ActiveJob's `queue_name` as the default queue, falling back to
38
+ # any explicit `zizq_queue` setting, then "default".
39
+ def zizq_queue: (?untyped name) -> untyped
40
+
41
+ # Serialize using ActiveJob's own format.
34
42
  #
35
43
  # Creates a temporary ActiveJob instance to produce the canonical
36
- # serialized form, including `_aj_ruby2_keywords` markers for kwargs.
37
- # This ensures unique key generation uses the same format as the
38
- # enqueued payload.
39
- #
40
- # This is needed so that unique job keys can be correctly generated.
44
+ # serialized form. Returns the full serialized hash (including
45
+ # `job_class`, `arguments`, `queue_name`, etc.) so that the payload
46
+ # stored in Zizq matches what `ActiveJob::Base.execute` expects.
41
47
  def zizq_serialize: (*untyped args, **untyped kwargs) -> untyped
42
48
 
43
49
  # Deserialization is handled by ActiveJob::Base.execute on the worker
44
50
  # side. This method is not used in the ActiveJob dispatch path.
45
51
  def zizq_deserialize: (untyped _payload) -> untyped
46
52
 
53
+ # Override unique key generation to hash only the arguments portion
54
+ # of the serialized payload. The full payload contains volatile fields
55
+ # (job_id, enqueued_at, etc.) that change per instance.
56
+ def zizq_unique_key: (*untyped args, **untyped kwargs) -> untyped
57
+
47
58
  # Generate a jq expression that exactly matches payloads with the given
48
59
  # arguments.
49
60
  #
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zizq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Corbyn <chris@zizq.io>
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-27 00:00:00.000000000 Z
11
+ date: 2026-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-http