activejob 7.1.5.1 → 7.2.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: 3163adeb0ad6bf21b0048cfcde214b97af34a0b49299f37cd2e93905a5839327
4
- data.tar.gz: ccaff11c2aa436b1ad0b7a479c030c7e241ee8e2c0a4754361ac6acb6a703d5f
3
+ metadata.gz: c3b47492def92c2f9d51610a3b8ca696cbb32ff69fe45107ebaf478a69abc65f
4
+ data.tar.gz: f05813374e5dec3e6b9e138585ef9ef23c87640187a42ea03e7db9d50d1e2362
5
5
  SHA512:
6
- metadata.gz: d319ffd95f49cddec8a0fdbc39f36d5029a3d7bc91086564cd673f784268a86d20c3d2977d248a8f7591e80d8652be11d9c9bd0e94afb5cbefad132035d1ad68
7
- data.tar.gz: e9eaebe18fc732613af2da14a35d5993f1c4c6e87ff01908fef6f569c51c395150046d1502d913df2bcb4cbeb0c2810bbe2d5a337f8903207e604dabba789509
6
+ metadata.gz: 58e96af8f140d46c83bc3d9231ee6e8c330d71e724def12d20844d5af4280b12a4de63ba3c7e58157d32295193c55405fb292071c6f0494416f66ea46ad658a6
7
+ data.tar.gz: a5f662c33aa37b48aa7643299cddaf5f76559feb7820468862b71aae7c0f725cf25ad098b0df2d951c810d76abaa10e49e24bdac3589b4c6bd9b683335856424
data/CHANGELOG.md CHANGED
@@ -1,310 +1,92 @@
1
- ## Rails 7.1.5.1 (December 10, 2024) ##
1
+ ## Rails 7.2.2.1 (December 10, 2024) ##
2
2
 
3
3
  * No changes.
4
4
 
5
5
 
6
- ## Rails 7.1.5 (October 30, 2024) ##
6
+ ## Rails 7.2.2 (October 30, 2024) ##
7
7
 
8
8
  * No changes.
9
9
 
10
10
 
11
- ## Rails 7.1.4.2 (October 23, 2024) ##
11
+ ## Rails 7.2.1.2 (October 23, 2024) ##
12
12
 
13
13
  * No changes.
14
14
 
15
15
 
16
- ## Rails 7.1.4.1 (October 15, 2024) ##
16
+ ## Rails 7.2.1.1 (October 15, 2024) ##
17
17
 
18
18
  * No changes.
19
19
 
20
20
 
21
- ## Rails 7.1.4 (August 22, 2024) ##
22
-
23
- * Register autoload for `ActiveJob::Arguments`.
24
-
25
- *Rafael Mendonça França*
26
-
27
-
28
- ## Rails 7.1.3.4 (June 04, 2024) ##
29
-
30
- * No changes.
31
-
32
-
33
- ## Rails 7.1.3.3 (May 16, 2024) ##
34
-
35
- * No changes.
36
-
37
-
38
- ## Rails 7.1.3.2 (February 21, 2024) ##
39
-
40
- * No changes.
41
-
42
-
43
- ## Rails 7.1.3.1 (February 21, 2024) ##
44
-
45
- * No changes.
46
-
47
-
48
- ## Rails 7.1.3 (January 16, 2024) ##
49
-
50
- * Do not trigger immediate loading of `ActiveJob::Base` when loading `ActiveJob::TestHelper`.
51
-
52
- *Maxime Réty*
53
-
54
- * Preserve the serialized timezone when deserializing `ActiveSupport::TimeWithZone` arguments.
55
-
56
- *Joshua Young*
57
-
58
- * Fix ActiveJob arguments serialization to correctly serialize String subclasses having custom serializers.
59
-
60
- *fatkodima*
61
-
62
-
63
- ## Rails 7.1.2 (November 10, 2023) ##
21
+ ## Rails 7.2.1 (August 22, 2024) ##
64
22
 
65
23
  * No changes.
66
24
 
67
25
 
68
- ## Rails 7.1.1 (October 11, 2023) ##
69
-
70
- * Don't log enqueuing details when the job wasn't enqueued.
71
-
72
- *Dustin Brown*
73
-
74
-
75
- ## Rails 7.1.0 (October 05, 2023) ##
76
-
77
- * No changes.
78
-
79
-
80
- ## Rails 7.1.0.rc2 (October 01, 2023) ##
81
-
82
- * Make sure `scheduled_at` is a Time object when asserting enqueued jobs.
83
-
84
- *Rafael Mendonça França*
85
-
86
-
87
- ## Rails 7.1.0.rc1 (September 27, 2023) ##
88
-
89
- * Set `scheduled_at` attribute as a Time object instead of epoch seconds, and serialize and deserialize the value
90
- when enqueued. Assigning a numeric/epoch value to scheduled_at= is deprecated; use a Time object instead.
91
-
92
- Deserializes `enqueued_at` as a Time instead of ISO8601 String.
93
-
94
- *Ben Sheldon*
95
-
96
- * Clarify the backoff strategy for the recommended `:wait` option when retrying jobs
97
-
98
- `wait: :exponentially_longer` is waiting polynomially longer, so it is now recommended to use `wait: :polynomially_longer` to keep the same behavior.
99
-
100
- *Victor Mours*
101
-
102
-
103
- ## Rails 7.1.0.beta1 (September 13, 2023) ##
104
-
105
- * Fix Active Job log message to correctly report a job failed to enqueue
106
- when the adapter raises an `ActiveJob::EnqueueError`.
107
-
108
- *Ben Sheldon*
109
-
110
- * Add `after_discard` method.
111
-
112
- This method lets job authors define a block which will be run when a job is about to be discarded. For example:
113
-
114
- ```ruby
115
- class AfterDiscardJob < ActiveJob::Base
116
- after_discard do |job, exception|
117
- Rails.logger.info("#{job.class} raised an exception: #{exception}")
118
- end
119
-
120
- def perform
121
- raise StandardError
122
- end
123
- end
124
- ```
125
-
126
- The above job will run the block passed to `after_discard` after the job is discarded. The exception will
127
- still be raised after the block has been run.
128
-
129
- *Rob Cardy*
26
+ ## Rails 7.2.0 (August 09, 2024) ##
130
27
 
131
- * Fix deserialization of ActiveSupport::Duration
28
+ * All tests now respect the `active_job.queue_adapter` config.
132
29
 
133
- Previously, a deserialized Duration would return an array from Duration#parts.
134
- It will now return a hash just like a regular Duration.
30
+ Previously if you had set `config.active_job.queue_adapter` in your `config/application.rb`
31
+ or `config/environments/test.rb` file, the adapter you selected was previously not used consistently
32
+ across all tests. In some tests your adapter would be used, but other tests would use the `TestAdapter`.
135
33
 
136
- This also fixes an error when trying to add or subtract from a deserialized Duration
137
- (eg `duration + 1.year`).
34
+ In Rails 7.2, all tests will respect the `queue_adapter` config if provided. If no config is provided,
35
+ the `TestAdapter` will continue to be used.
138
36
 
139
- *Jonathan del Strother*
140
-
141
- * `perform_enqueued_jobs` is now compatible with all Active Job adapters
142
-
143
- This means that methods that depend on it, like Action Mailer's `assert_emails`,
144
- will work correctly even if the test adapter is not used.
37
+ See [#48585](https://github.com/rails/rails/pull/48585) for more details.
145
38
 
146
39
  *Alex Ghiculescu*
147
40
 
148
- * Allow queue adapters to provide a custom name by implementing `queue_adapter_name`
149
-
150
- *Sander Verdonschot*
151
-
152
- * Log background job enqueue callers
153
-
154
- Add `verbose_enqueue_logs` configuration option to display the caller
155
- of background job enqueue in the log to help with debugging.
156
-
157
- Example log line:
158
-
159
- ```
160
- Enqueued AvatarThumbnailsJob (Job ID: ab528951-41fb-4c48-9129-3171791c27d6) to Sidekiq(default) with arguments: 1092412064
161
- ↳ app/models/user.rb:421:in `generate_avatar_thumbnails'
162
- ```
163
-
164
- Enabled in development only for new and upgraded applications. Not recommended for use
165
- in the production environment since it relies on Ruby's `Kernel#caller` which is fairly slow.
166
-
167
- *fatkodima*
41
+ * Make Active Job transaction aware when used conjointly with Active Record.
168
42
 
169
- * Set `provider_job_id` for Backburner jobs
170
-
171
- *Cameron Matheson*
172
-
173
- * Add `perform_all_later` to enqueue multiple jobs at once
174
-
175
- This adds the ability to bulk enqueue jobs, without running callbacks, by
176
- passing multiple jobs or an array of jobs. For example:
43
+ A common mistake with Active Job is to enqueue jobs from inside a transaction,
44
+ causing them to potentially be picked and ran by another process, before the
45
+ transaction is committed, which may result in various errors.
177
46
 
178
47
  ```ruby
179
- ActiveJob.perform_all_later(MyJob.new("hello", 42), MyJob.new("world", 0))
180
-
181
- user_jobs = User.pluck(:id).map { |id| UserJob.new(user_id: id) }
182
- ActiveJob.perform_all_later(user_jobs)
48
+ Topic.transaction do
49
+ topic = Topic.create(...)
50
+ NewTopicNotificationJob.perform_later(topic)
51
+ end
183
52
  ```
184
53
 
185
- This can greatly reduce the number of round-trips to the queue datastore.
186
- For queue adapters that do not implement the new `enqueue_all` method, we
187
- fall back to enqueuing jobs individually. The Sidekiq adapter implements
188
- `enqueue_all` with `push_bulk`.
189
-
190
- This method does not use the existing `enqueue.active_job` event, but adds a
191
- new event `enqueue_all.active_job`.
192
-
193
- *Sander Verdonschot*
194
-
195
- * Don't double log the `job` when using `ActiveRecord::QueryLog`
196
-
197
- Previously if you set `config.active_record.query_log_tags` to an array that included
198
- `:job`, the job name would get logged twice. This bug has been fixed.
199
-
200
- *Alex Ghiculescu*
201
-
202
- * Add support for Sidekiq's transaction-aware client
203
-
204
- *Jonathan del Strother*
205
-
206
- * Remove QueAdapter from Active Job.
207
-
208
- After maintaining Active Job QueAdapter by Rails and Que side
209
- to support Ruby 3 keyword arguments and options provided as top level keywords,
210
- it is quite difficult to maintain it this way.
54
+ Now Active Job will automatically defer the enqueuing to after the transaction is committed,
55
+ and drop the job if the transaction is rolled back.
211
56
 
212
- Active Job Que adapter can be included in the future version of que gem itself.
213
-
214
- *Yasuo Honda*
215
-
216
- * Fix BigDecimal (de)serialization for adapters using JSON.
217
-
218
- Previously, BigDecimal was listed as not needing a serializer. However,
219
- when used with an adapter storing the job arguments as JSON, it would get
220
- serialized as a simple String, resulting in deserialization also producing
221
- a String (instead of a BigDecimal).
222
-
223
- By using a serializer, we ensure the round trip is safe.
224
-
225
- To ensure applications using BigDecimal job arguments are not subject to
226
- race conditions during deployment (where a replica running a version of
227
- Rails without BigDecimalSerializer fails to deserialize an argument
228
- serialized with it), `ActiveJob.use_big_decimal_serializer` is disabled by
229
- default, and can be set to true in a following deployment..
230
-
231
- *Sam Bostock*
232
-
233
- * Preserve full-precision `enqueued_at` timestamps for serialized jobs,
234
- allowing more accurate reporting of how long a job spent waiting in the
235
- queue before it was performed.
236
-
237
- Retains IS08601 format compatibility.
238
-
239
- *Jeremy Daer*
240
-
241
- * Add `--parent` option to job generator to specify parent class of job.
242
-
243
- Example:
244
-
245
- `bin/rails g job process_payment --parent=payment_job` generates:
57
+ Various queue implementations can choose to disable this behavior, and users can disable it,
58
+ or force it on a per job basis:
246
59
 
247
60
  ```ruby
248
- class ProcessPaymentJob < PaymentJob
249
- # ...
61
+ class NewTopicNotificationJob < ApplicationJob
62
+ self.enqueue_after_transaction_commit = :never # or `:always` or `:default`
250
63
  end
251
64
  ```
252
65
 
253
- *Gannon McGibbon*
254
-
255
- * Add more detailed description to job generator.
256
-
257
- *Gannon McGibbon*
258
-
259
- * `perform.active_job` notification payloads now include `:db_runtime`, which
260
- is the total time (in ms) taken by database queries while performing a job.
261
- This value can be used to better understand how a job's time is spent.
66
+ *Jean Boussier*, *Cristian Bica*
262
67
 
263
- *Jonathan Hefner*
264
-
265
- * Update `ActiveJob::QueueAdapters::QueAdapter` to remove deprecation warning.
266
-
267
- Remove a deprecation warning introduced in que 1.2 to prepare for changes in
268
- que 2.0 necessary for Ruby 3 compatibility.
269
-
270
- *Damir Zekic* and *Adis Hasovic*
68
+ * Do not trigger immediate loading of `ActiveJob::Base` when loading `ActiveJob::TestHelper`.
271
69
 
272
- * Add missing `bigdecimal` require in `ActiveJob::Arguments`
70
+ *Maxime Réty*
273
71
 
274
- Could cause `uninitialized constant ActiveJob::Arguments::BigDecimal (NameError)`
275
- when loading Active Job in isolation.
72
+ * Preserve the serialized timezone when deserializing `ActiveSupport::TimeWithZone` arguments.
276
73
 
277
- *Jean Boussier*
74
+ *Joshua Young*
278
75
 
279
- * Allow testing `discard_on/retry_on ActiveJob::DeserializationError`
76
+ * Remove deprecated `:exponentially_longer` value for the `:wait` in `retry_on`.
280
77
 
281
- Previously in `perform_enqueued_jobs`, `deserialize_arguments_if_needed`
282
- was called before calling `perform_now`. When a record no longer exists
283
- and is serialized using GlobalID this led to raising
284
- an `ActiveJob::DeserializationError` before reaching `perform_now` call.
285
- This behavior makes difficult testing the job `discard_on/retry_on` logic.
78
+ *Rafael Mendonça França*
286
79
 
287
- Now `deserialize_arguments_if_needed` call is postponed to when `perform_now`
288
- is called.
80
+ * Remove deprecated support to set numeric values to `scheduled_at` attribute.
289
81
 
290
- Example:
82
+ *Rafael Mendonça França*
291
83
 
292
- ```ruby
293
- class UpdateUserJob < ActiveJob::Base
294
- discard_on ActiveJob::DeserializationError
84
+ * Deprecate `Rails.application.config.active_job.use_big_decimal_serialize`.
295
85
 
296
- def perform(user)
297
- # ...
298
- end
299
- end
86
+ *Rafael Mendonça França*
300
87
 
301
- # In the test
302
- User.destroy_all
303
- assert_nothing_raised do
304
- perform_enqueued_jobs only: UpdateUserJob
305
- end
306
- ```
88
+ * Remove deprecated primitive serializer for `BigDecimal` arguments.
307
89
 
308
- *Jacopo Beschi*
90
+ *Rafael Mendonça França*
309
91
 
310
- Please check [7-0-stable](https://github.com/rails/rails/blob/7-0-stable/activejob/CHANGELOG.md) for previous changes.
92
+ Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/activejob/CHANGELOG.md) for previous changes.
@@ -101,15 +101,6 @@ module ActiveJob
101
101
  else
102
102
  if argument.respond_to?(:permitted?) && argument.respond_to?(:to_h)
103
103
  serialize_indifferent_hash(argument.to_h)
104
- elsif BigDecimal === argument && !ActiveJob.use_big_decimal_serializer
105
- ActiveJob.deprecator.warn(<<~MSG)
106
- Primitive serialization of BigDecimal job arguments is deprecated as it may serialize via .to_s using certain queue adapters.
107
- Enable config.active_job.use_big_decimal_serializer to use BigDecimalSerializer instead, which will be mandatory in Rails 7.2.
108
-
109
- Note that if your application has multiple replicas, you should only enable this setting after successfully deploying your app to Rails 7.1 first.
110
- This will ensure that during your deployment all replicas are capable of deserializing arguments serialized with BigDecimalSerializer.
111
- MSG
112
- argument
113
104
  else
114
105
  Serializers.serialize(argument)
115
106
  end
@@ -120,8 +111,6 @@ module ActiveJob
120
111
  case argument
121
112
  when nil, true, false, String, Integer, Float
122
113
  argument
123
- when BigDecimal # BigDecimal may have been legacy serialized; Remove in 7.2
124
- argument
125
114
  when Array
126
115
  argument.map { |arg| deserialize_argument(arg) }
127
116
  when Hash
@@ -15,9 +15,6 @@ module ActiveJob
15
15
  # * <tt>before_perform</tt>
16
16
  # * <tt>around_perform</tt>
17
17
  # * <tt>after_perform</tt>
18
- #
19
- # NOTE: Calling the same callback multiple times will overwrite previous callback definitions.
20
- #
21
18
  module Callbacks
22
19
  extend ActiveSupport::Concern
23
20
  include ActiveSupport::Callbacks
@@ -13,9 +13,7 @@ module ActiveJob
13
13
  attr_writer :serialized_arguments
14
14
 
15
15
  # Time when the job should be performed
16
- attr_reader :scheduled_at
17
-
18
- attr_reader :_scheduled_at_time # :nodoc:
16
+ attr_accessor :scheduled_at
19
17
 
20
18
  # Job Identifier
21
19
  attr_accessor :job_id
@@ -97,7 +95,6 @@ module ActiveJob
97
95
  @job_id = SecureRandom.uuid
98
96
  @queue_name = self.class.queue_name
99
97
  @scheduled_at = nil
100
- @_scheduled_at_time = nil
101
98
  @priority = self.class.priority
102
99
  @executions = 0
103
100
  @exception_executions = {}
@@ -120,7 +117,7 @@ module ActiveJob
120
117
  "locale" => I18n.locale.to_s,
121
118
  "timezone" => timezone,
122
119
  "enqueued_at" => Time.now.utc.iso8601(9),
123
- "scheduled_at" => _scheduled_at_time ? _scheduled_at_time.utc.iso8601(9) : nil,
120
+ "scheduled_at" => scheduled_at ? scheduled_at.utc.iso8601(9) : nil,
124
121
  }
125
122
  end
126
123
 
@@ -174,18 +171,6 @@ module ActiveJob
174
171
  self
175
172
  end
176
173
 
177
- def scheduled_at=(value)
178
- @_scheduled_at_time = if value&.is_a?(Numeric)
179
- ActiveJob.deprecator.warn(<<~MSG.squish)
180
- Assigning a numeric/epoch value to scheduled_at is deprecated. Use a Time object instead.
181
- MSG
182
- Time.at(value)
183
- else
184
- value
185
- end
186
- @scheduled_at = value
187
- end
188
-
189
174
  private
190
175
  def serialize_arguments_if_needed(arguments)
191
176
  if arguments_serialized?
@@ -211,7 +196,7 @@ module ActiveJob
211
196
  end
212
197
 
213
198
  def arguments_serialized?
214
- defined?(@serialized_arguments) && @serialized_arguments
199
+ @serialized_arguments
215
200
  end
216
201
  end
217
202
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveJob
4
+ module EnqueueAfterTransactionCommit # :nodoc:
5
+ private
6
+ def raw_enqueue
7
+ after_transaction = case self.class.enqueue_after_transaction_commit
8
+ when :always
9
+ true
10
+ when :never
11
+ false
12
+ else # :default
13
+ queue_adapter.enqueue_after_transaction_commit?
14
+ end
15
+
16
+ if after_transaction
17
+ self.successfully_enqueued = true
18
+ ActiveRecord.after_all_transactions_commit do
19
+ self.successfully_enqueued = false
20
+ super
21
+ end
22
+ self
23
+ else
24
+ super
25
+ end
26
+ end
27
+ end
28
+ end
@@ -21,7 +21,7 @@ module ActiveJob
21
21
  adapter_jobs.each do |job|
22
22
  job.successfully_enqueued = false
23
23
  if job.scheduled_at
24
- queue_adapter.enqueue_at(job, job._scheduled_at_time.to_f)
24
+ queue_adapter.enqueue_at(job, job.scheduled_at.to_f)
25
25
  else
26
26
  queue_adapter.enqueue(job)
27
27
  end
@@ -40,6 +40,20 @@ module ActiveJob
40
40
  module Enqueuing
41
41
  extend ActiveSupport::Concern
42
42
 
43
+ included do
44
+ ##
45
+ # :singleton-method:
46
+ #
47
+ # Defines if enqueueing this job from inside an Active Record transaction
48
+ # automatically defers the enqueue to after the transaction commits.
49
+ #
50
+ # It can be set on a per job basis:
51
+ # - `:always` forces the job to be deferred.
52
+ # - `:never` forces the job to be queued immediately.
53
+ # - `:default` lets the queue adapter define the behavior (recommended).
54
+ class_attribute :enqueue_after_transaction_commit, instance_accessor: false, instance_predicate: false, default: :never
55
+ end
56
+
43
57
  # Includes the +perform_later+ method for job initialization.
44
58
  module ClassMethods
45
59
  # Push a job onto the queue. By default the arguments must be either String,
@@ -50,9 +64,21 @@ module ActiveJob
50
64
  # custom serializers.
51
65
  #
52
66
  # Returns an instance of the job class queued with arguments available in
53
- # Job#arguments or false if the enqueue did not succeed.
67
+ # Job#arguments or +false+ if the enqueue did not succeed.
54
68
  #
55
69
  # After the attempted enqueue, the job will be yielded to an optional block.
70
+ #
71
+ # If Active Job is used conjointly with Active Record, and #perform_later is called
72
+ # inside an Active Record transaction, then the enqueue is implicitly deferred to after
73
+ # the transaction is committed, or dropped if it's rolled back. In such case #perform_later
74
+ # will return the job instance like if it was successfully enqueued, but will still return
75
+ # +false+ if a callback prevented the job from being enqueued.
76
+ #
77
+ # This behavior can be changed on a per job basis:
78
+ #
79
+ # class NotificationJob < ApplicationJob
80
+ # self.enqueue_after_transaction_commit = false
81
+ # end
56
82
  def perform_later(...)
57
83
  job = job_or_instantiate(...)
58
84
  enqueue_result = job.enqueue
@@ -63,7 +89,7 @@ module ActiveJob
63
89
  end
64
90
 
65
91
  private
66
- def job_or_instantiate(*args) # :doc:
92
+ def job_or_instantiate(*args, &_) # :doc:
67
93
  args.first.is_a?(self) ? args.first : new(*args)
68
94
  end
69
95
  ruby2_keywords(:job_or_instantiate)
@@ -89,8 +115,20 @@ module ActiveJob
89
115
  self.successfully_enqueued = false
90
116
 
91
117
  run_callbacks :enqueue do
118
+ raw_enqueue
119
+ end
120
+
121
+ if successfully_enqueued?
122
+ self
123
+ else
124
+ false
125
+ end
126
+ end
127
+
128
+ private
129
+ def raw_enqueue
92
130
  if scheduled_at
93
- queue_adapter.enqueue_at self, _scheduled_at_time.to_f
131
+ queue_adapter.enqueue_at self, scheduled_at.to_f
94
132
  else
95
133
  queue_adapter.enqueue self
96
134
  end
@@ -99,12 +137,5 @@ module ActiveJob
99
137
  rescue EnqueueError => e
100
138
  self.enqueue_error = e
101
139
  end
102
-
103
- if successfully_enqueued?
104
- self
105
- else
106
- false
107
- end
108
- end
109
140
  end
110
141
  end
@@ -21,7 +21,7 @@ module ActiveJob
21
21
  # You can also pass a block that'll be invoked if the retry attempts fail for custom logic rather than letting
22
22
  # the exception bubble up. This block is yielded with the job instance as the first and the error instance as the second parameter.
23
23
  #
24
- # `retry_on` and `discard_on` handlers are searched from bottom to top, and up the class hierarchy. The handler of the first class for
24
+ # +retry_on+ and +discard_on+ handlers are searched from bottom to top, and up the class hierarchy. The handler of the first class for
25
25
  # which <tt>exception.is_a?(klass)</tt> holds true is the one invoked, if any.
26
26
  #
27
27
  # ==== Options
@@ -29,8 +29,8 @@ module ActiveJob
29
29
  # as a computing proc that takes the number of executions so far as an argument, or as a symbol reference of
30
30
  # <tt>:polynomially_longer</tt>, which applies the wait algorithm of <tt>((executions**4) + (Kernel.rand * (executions**4) * jitter)) + 2</tt>
31
31
  # (first wait ~3s, then ~18s, then ~83s, etc)
32
- # * <tt>:attempts</tt> - Re-enqueues the job the specified number of times (default: 5 attempts) or a symbol reference of <tt>:unlimited</tt>
33
- # to retry the job until it succeeds
32
+ # * <tt>:attempts</tt> - Enqueues the job the specified number of times (default: 5 attempts) or a symbol reference of <tt>:unlimited</tt>
33
+ # to retry the job until it succeeds. The number of attempts includes the original job execution.
34
34
  # * <tt>:queue</tt> - Re-enqueues the job on a different queue
35
35
  # * <tt>:priority</tt> - Re-enqueues the job with a different priority
36
36
  # * <tt>:jitter</tt> - A random delay of wait time used when calculating backoff. The default is 15% (0.15) which represents the upper bound of possible wait time (expressed as a percentage)
@@ -60,12 +60,6 @@ module ActiveJob
60
60
  # end
61
61
  # end
62
62
  def retry_on(*exceptions, wait: 3.seconds, attempts: 5, queue: nil, priority: nil, jitter: JITTER_DEFAULT)
63
- if wait == :exponentially_longer
64
- ActiveJob.deprecator.warn(<<~MSG.squish)
65
- `wait: :exponentially_longer` will actually wait polynomially longer and is therefore deprecated.
66
- Prefer `wait: :polynomially_longer` to avoid confusion and keep the same behavior.
67
- MSG
68
- end
69
63
  rescue_from(*exceptions) do |error|
70
64
  executions = executions_for(exceptions)
71
65
  if attempts == :unlimited || executions < attempts
@@ -90,7 +84,7 @@ module ActiveJob
90
84
  #
91
85
  # You can also pass a block that'll be invoked. This block is yielded with the job instance as the first and the error instance as the second parameter.
92
86
  #
93
- # `retry_on` and `discard_on` handlers are searched from bottom to top, and up the class hierarchy. The handler of the first class for
87
+ # +retry_on+ and +discard_on+ handlers are searched from bottom to top, and up the class hierarchy. The handler of the first class for
94
88
  # which <tt>exception.is_a?(klass)</tt> holds true is the one invoked, if any.
95
89
  #
96
90
  # ==== Example
@@ -168,7 +162,7 @@ module ActiveJob
168
162
  jitter = jitter == JITTER_DEFAULT ? self.class.retry_jitter : (jitter || 0.0)
169
163
 
170
164
  case seconds_or_duration_or_algorithm
171
- when :exponentially_longer, :polynomially_longer
165
+ when :polynomially_longer
172
166
  # This delay uses a polynomial backoff strategy, which was previously misnamed as exponential
173
167
  delay = executions**4
174
168
  delay_jitter = determine_jitter_for_delay(delay, jitter)
@@ -8,8 +8,8 @@ module ActiveJob
8
8
 
9
9
  module VERSION
10
10
  MAJOR = 7
11
- MINOR = 1
12
- TINY = 5
11
+ MINOR = 2
12
+ TINY = 2
13
13
  PRE = "1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
@@ -125,7 +125,7 @@ module ActiveJob
125
125
  "Stopped retrying #{job.class} (Job ID: #{job.job_id}) due to a #{ex.class} (#{ex.message}), which reoccurred on #{job.executions} attempts."
126
126
  end
127
127
  end
128
- subscribe_log_level :enqueue_retry, :error
128
+ subscribe_log_level :retry_stopped, :error
129
129
 
130
130
  def discard(event)
131
131
  job = event.payload[:job]
@@ -4,17 +4,31 @@ require "active_support/tagged_logging"
4
4
  require "active_support/logger"
5
5
 
6
6
  module ActiveJob
7
- module Logging # :nodoc:
7
+ module Logging
8
8
  extend ActiveSupport::Concern
9
9
 
10
10
  included do
11
+ ##
12
+ # Accepts a logger conforming to the interface of Log4r or the default
13
+ # Ruby +Logger+ class. You can retrieve this logger by calling +logger+ on
14
+ # either an Active Job job class or an Active Job job instance.
11
15
  cattr_accessor :logger, default: ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT))
16
+
17
+ ##
18
+ # Configures whether a job's arguments should be logged. This can be
19
+ # useful when a job's arguments may be sensitive and so should not be
20
+ # logged.
21
+ #
22
+ # The value defaults to +true+, but this can be configured with
23
+ # +config.active_job.log_arguments+. Additionally, individual jobs can
24
+ # also configure a value, which will apply to themselves and any
25
+ # subclasses.
12
26
  class_attribute :log_arguments, instance_accessor: false, default: true
13
27
 
14
28
  around_enqueue(prepend: true) { |_, block| tag_logger(&block) }
15
29
  end
16
30
 
17
- def perform_now
31
+ def perform_now # :nodoc:
18
32
  tag_logger(self.class.name, self.job_id) { super }
19
33
  end
20
34
 
@@ -15,7 +15,8 @@ module ActiveJob
15
15
  # = Active Job Queue adapter
16
16
  #
17
17
  # The +ActiveJob::QueueAdapter+ module is used to load the
18
- # correct adapter. The default queue adapter is the +:async+ queue.
18
+ # correct adapter. The default queue adapter is +:async+,
19
+ # which loads the ActiveJob::QueueAdapters::AsyncAdapter.
19
20
  module QueueAdapter # :nodoc:
20
21
  extend ActiveSupport::Concern
21
22
 
@@ -24,21 +25,21 @@ module ActiveJob
24
25
  class_attribute :_queue_adapter, instance_accessor: false, instance_predicate: false
25
26
 
26
27
  delegate :queue_adapter, to: :class
27
-
28
- self.queue_adapter = :async
29
28
  end
30
29
 
31
30
  # Includes the setter method for changing the active queue adapter.
32
31
  module ClassMethods
33
32
  # Returns the backend queue provider. The default queue adapter
34
- # is the +:async+ queue. See QueueAdapters for more information.
33
+ # is +:async+. See QueueAdapters for more information.
35
34
  def queue_adapter
35
+ self.queue_adapter = :async if _queue_adapter.nil?
36
36
  _queue_adapter
37
37
  end
38
38
 
39
39
  # Returns string denoting the name of the configured queue adapter.
40
40
  # By default returns <tt>"async"</tt>.
41
41
  def queue_adapter_name
42
+ self.queue_adapter = :async if _queue_adapter_name.nil?
42
43
  _queue_adapter_name
43
44
  end
44
45
 
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveJob
4
+ module QueueAdapters
5
+ # = Active Job Abstract Adapter
6
+ #
7
+ # Active Job supports multiple job queue systems. ActiveJob::QueueAdapters::AbstractAdapter
8
+ # forms the abstraction layer which makes this possible.
9
+ class AbstractAdapter
10
+ # Defines whether enqueuing should happen implicitly to after commit when called
11
+ # from inside a transaction. Most adapters should return true, but some adapters
12
+ # that use the same database as Active Record and are transaction aware can return
13
+ # false to continue enqueuing jobs as part of the transaction.
14
+ def enqueue_after_transaction_commit?
15
+ true
16
+ end
17
+
18
+ def enqueue(job)
19
+ raise NotImplementedError
20
+ end
21
+
22
+ def enqueue_at(job, timestamp)
23
+ raise NotImplementedError
24
+ end
25
+ end
26
+ end
27
+ end
@@ -30,7 +30,7 @@ module ActiveJob
30
30
  # The adapter uses a {Concurrent Ruby}[https://github.com/ruby-concurrency/concurrent-ruby] thread pool to schedule and execute
31
31
  # jobs. Since jobs share a single thread pool, long-running jobs will block
32
32
  # short-lived jobs. Fine for dev/test; bad for production.
33
- class AsyncAdapter
33
+ class AsyncAdapter < AbstractAdapter
34
34
  # See {Concurrent::ThreadPoolExecutor}[https://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ThreadPoolExecutor.html] for executor options.
35
35
  def initialize(**executor_options)
36
36
  @scheduler = Scheduler.new(**executor_options)
@@ -14,7 +14,7 @@ module ActiveJob
14
14
  # To use Backburner set the queue_adapter config to +:backburner+.
15
15
  #
16
16
  # Rails.application.config.active_job.queue_adapter = :backburner
17
- class BackburnerAdapter
17
+ class BackburnerAdapter < AbstractAdapter
18
18
  def enqueue(job) # :nodoc:
19
19
  response = Backburner::Worker.enqueue(JobWrapper, [job.serialize], queue: job.queue_name, pri: job.priority)
20
20
  job.provider_job_id = response[:id] if response.is_a?(Hash)
@@ -15,7 +15,15 @@ module ActiveJob
15
15
  # To use Delayed Job, set the queue_adapter config to +:delayed_job+.
16
16
  #
17
17
  # Rails.application.config.active_job.queue_adapter = :delayed_job
18
- class DelayedJobAdapter
18
+ class DelayedJobAdapter < AbstractAdapter
19
+ def initialize(enqueue_after_transaction_commit: false)
20
+ @enqueue_after_transaction_commit = enqueue_after_transaction_commit
21
+ end
22
+
23
+ def enqueue_after_transaction_commit? # :nodoc:
24
+ @enqueue_after_transaction_commit
25
+ end
26
+
19
27
  def enqueue(job) # :nodoc:
20
28
  delayed_job = Delayed::Job.enqueue(JobWrapper.new(job.serialize), queue: job.queue_name, priority: job.priority)
21
29
  job.provider_job_id = delayed_job.id
@@ -10,7 +10,11 @@ module ActiveJob
10
10
  # To use the Inline set the queue_adapter config to +:inline+.
11
11
  #
12
12
  # Rails.application.config.active_job.queue_adapter = :inline
13
- class InlineAdapter
13
+ class InlineAdapter < AbstractAdapter
14
+ def enqueue_after_transaction_commit? # :nodoc:
15
+ false
16
+ end
17
+
14
18
  def enqueue(job) # :nodoc:
15
19
  Base.execute(job.serialize)
16
20
  end
@@ -18,7 +18,15 @@ module ActiveJob
18
18
  # To use queue_classic set the queue_adapter config to +:queue_classic+.
19
19
  #
20
20
  # Rails.application.config.active_job.queue_adapter = :queue_classic
21
- class QueueClassicAdapter
21
+ class QueueClassicAdapter < AbstractAdapter
22
+ def initialize(enqueue_after_transaction_commit: false)
23
+ @enqueue_after_transaction_commit = enqueue_after_transaction_commit
24
+ end
25
+
26
+ def enqueue_after_transaction_commit? # :nodoc:
27
+ @enqueue_after_transaction_commit
28
+ end
29
+
22
30
  def enqueue(job) # :nodoc:
23
31
  qc_job = build_queue(job.queue_name).enqueue("#{JobWrapper.name}.perform", job.serialize)
24
32
  job.provider_job_id = qc_job["id"] if qc_job.is_a?(Hash)
@@ -27,7 +27,7 @@ module ActiveJob
27
27
  # To use Resque set the queue_adapter config to +:resque+.
28
28
  #
29
29
  # Rails.application.config.active_job.queue_adapter = :resque
30
- class ResqueAdapter
30
+ class ResqueAdapter < AbstractAdapter
31
31
  def enqueue(job) # :nodoc:
32
32
  JobWrapper.instance_variable_set(:@queue, job.queue_name)
33
33
  Resque.enqueue_to job.queue_name, JobWrapper, job.serialize
@@ -17,7 +17,7 @@ module ActiveJob
17
17
  # To use Sidekiq set the queue_adapter config to +:sidekiq+.
18
18
  #
19
19
  # Rails.application.config.active_job.queue_adapter = :sidekiq
20
- class SidekiqAdapter
20
+ class SidekiqAdapter < AbstractAdapter
21
21
  def enqueue(job) # :nodoc:
22
22
  job.provider_job_id = JobWrapper.set(
23
23
  wrapped: job.class,
@@ -17,7 +17,7 @@ module ActiveJob
17
17
  # To use Sneakers set the queue_adapter config to +:sneakers+.
18
18
  #
19
19
  # Rails.application.config.active_job.queue_adapter = :sneakers
20
- class SneakersAdapter
20
+ class SneakersAdapter < AbstractAdapter
21
21
  def initialize
22
22
  @monitor = Monitor.new
23
23
  end
@@ -17,7 +17,7 @@ module ActiveJob
17
17
  # To use Sucker Punch set the queue_adapter config to +:sucker_punch+.
18
18
  #
19
19
  # Rails.application.config.active_job.queue_adapter = :sucker_punch
20
- class SuckerPunchAdapter
20
+ class SuckerPunchAdapter < AbstractAdapter
21
21
  def enqueue(job) # :nodoc:
22
22
  if JobWrapper.respond_to?(:perform_async)
23
23
  # sucker_punch 2.0 API
@@ -11,10 +11,18 @@ module ActiveJob
11
11
  # To use the test adapter set +queue_adapter+ config to +:test+.
12
12
  #
13
13
  # Rails.application.config.active_job.queue_adapter = :test
14
- class TestAdapter
15
- attr_accessor(:perform_enqueued_jobs, :perform_enqueued_at_jobs, :filter, :reject, :queue, :at)
14
+ class TestAdapter < AbstractAdapter
15
+ attr_accessor(:perform_enqueued_jobs, :perform_enqueued_at_jobs, :filter, :reject, :queue, :at, :enqueue_after_transaction_commit)
16
16
  attr_writer(:enqueued_jobs, :performed_jobs)
17
17
 
18
+ def initialize(enqueue_after_transaction_commit: true)
19
+ @enqueue_after_transaction_commit = enqueue_after_transaction_commit
20
+ end
21
+
22
+ def enqueue_after_transaction_commit? # :nodoc:
23
+ @enqueue_after_transaction_commit
24
+ end
25
+
18
26
  # Provides a store of all the enqueued jobs with the TestAdapter so you can check them.
19
27
  def enqueued_jobs
20
28
  @enqueued_jobs ||= []
@@ -114,6 +114,7 @@ module ActiveJob
114
114
  module QueueAdapters
115
115
  extend ActiveSupport::Autoload
116
116
 
117
+ autoload :AbstractAdapter
117
118
  autoload :AsyncAdapter
118
119
  autoload :InlineAdapter
119
120
  autoload :BackburnerAdapter
@@ -25,9 +25,21 @@ module ActiveJob
25
25
  end
26
26
  end
27
27
 
28
+ initializer "active_job.enqueue_after_transaction_commit" do |app|
29
+ ActiveSupport.on_load(:active_job) do
30
+ ActiveSupport.on_load(:active_record) do
31
+ ActiveJob::Base.include EnqueueAfterTransactionCommit
32
+
33
+ if app.config.active_job.key?(:enqueue_after_transaction_commit)
34
+ ActiveJob::Base.enqueue_after_transaction_commit = app.config.active_job.delete(:enqueue_after_transaction_commit)
35
+ end
36
+ end
37
+ end
38
+ end
39
+
28
40
  initializer "active_job.set_configs" do |app|
29
41
  options = app.config.active_job
30
- options.queue_adapter ||= :async
42
+ options.queue_adapter ||= (Rails.env.test? ? :test : :async)
31
43
 
32
44
  config.after_initialize do
33
45
  options.each do |k, v|
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "singleton"
4
+
3
5
  module ActiveJob
4
6
  module Serializers
5
7
  # Base class for serializing and deserializing custom objects.
@@ -39,10 +39,13 @@ module ActiveJob
39
39
  end
40
40
 
41
41
  def before_setup # :nodoc:
42
- test_adapter = queue_adapter_for_test
43
-
42
+ queue_adapter_specific_to_this_test_class = queue_adapter_for_test
44
43
  queue_adapter_changed_jobs.each do |klass|
45
- klass.enable_test_adapter(test_adapter)
44
+ if queue_adapter_specific_to_this_test_class
45
+ klass.enable_test_adapter(queue_adapter_specific_to_this_test_class)
46
+ elsif klass._queue_adapter.nil?
47
+ klass.enable_test_adapter(ActiveJob::QueueAdapters::TestAdapter.new)
48
+ end
46
49
  end
47
50
 
48
51
  clear_enqueued_jobs
@@ -61,7 +64,6 @@ module ActiveJob
61
64
  # Override this method to specify a different adapter. The adapter must
62
65
  # implement the same interface as ActiveJob::QueueAdapters::TestAdapter.
63
66
  def queue_adapter_for_test
64
- ActiveJob::QueueAdapters::TestAdapter.new
65
67
  end
66
68
 
67
69
  # Asserts that the number of enqueued jobs matches the given number.
@@ -118,6 +120,8 @@ module ActiveJob
118
120
  # end
119
121
  # end
120
122
  def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil, &block)
123
+ require_active_job_test_adapter!("assert_enqueued_jobs")
124
+
121
125
  if block_given?
122
126
  original_jobs = enqueued_jobs_with(only: only, except: except, queue: queue)
123
127
 
@@ -180,6 +184,8 @@ module ActiveJob
180
184
  #
181
185
  # assert_enqueued_jobs 0, &block
182
186
  def assert_no_enqueued_jobs(only: nil, except: nil, queue: nil, &block)
187
+ require_active_job_test_adapter!("assert_no_enqueued_jobs")
188
+
183
189
  assert_enqueued_jobs 0, only: only, except: except, queue: queue, &block
184
190
  end
185
191
 
@@ -270,6 +276,8 @@ module ActiveJob
270
276
  # end
271
277
  # end
272
278
  def assert_performed_jobs(number, only: nil, except: nil, queue: nil, &block)
279
+ require_active_job_test_adapter!("assert_performed_jobs")
280
+
273
281
  if block_given?
274
282
  original_count = performed_jobs.size
275
283
 
@@ -338,6 +346,8 @@ module ActiveJob
338
346
  #
339
347
  # assert_performed_jobs 0, &block
340
348
  def assert_no_performed_jobs(only: nil, except: nil, queue: nil, &block)
349
+ require_active_job_test_adapter!("assert_no_performed_jobs")
350
+
341
351
  assert_performed_jobs 0, only: only, except: except, queue: queue, &block
342
352
  end
343
353
 
@@ -394,6 +404,8 @@ module ActiveJob
394
404
  # end
395
405
  # end
396
406
  def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil, priority: nil, &block)
407
+ require_active_job_test_adapter!("assert_enqueued_with")
408
+
397
409
  expected = { job: job, args: args, at: at, queue: queue, priority: priority }.compact
398
410
  expected_args = prepare_args_for_assertion(expected)
399
411
  potential_matches = []
@@ -496,6 +508,8 @@ module ActiveJob
496
508
  # end
497
509
  # end
498
510
  def assert_performed_with(job: nil, args: nil, at: nil, queue: nil, priority: nil, &block)
511
+ require_active_job_test_adapter!("assert_performed_with")
512
+
499
513
  expected = { job: job, args: args, at: at, queue: queue, priority: priority }.compact
500
514
  expected_args = prepare_args_for_assertion(expected)
501
515
  potential_matches = []
@@ -604,7 +618,10 @@ module ActiveJob
604
618
  # If queue_adapter_for_test is overridden to return a different adapter,
605
619
  # +perform_enqueued_jobs+ will merely execute the block.
606
620
  def perform_enqueued_jobs(only: nil, except: nil, queue: nil, at: nil, &block)
607
- return flush_enqueued_jobs(only: only, except: except, queue: queue, at: at) unless block_given?
621
+ unless block_given?
622
+ require_active_job_test_adapter!("perform_enqueued_jobs (without a block)")
623
+ return flush_enqueued_jobs(only: only, except: except, queue: queue, at: at)
624
+ end
608
625
 
609
626
  return _assert_nothing_raised_or_warn("perform_enqueued_jobs", &block) unless using_test_adapter?
610
627
 
@@ -646,6 +663,12 @@ module ActiveJob
646
663
  end
647
664
 
648
665
  private
666
+ def require_active_job_test_adapter!(method)
667
+ unless using_test_adapter?
668
+ raise ArgumentError.new("#{method} requires the Active Job test adapter, you're using #{queue_adapter.class.name}.")
669
+ end
670
+ end
671
+
649
672
  def using_test_adapter?
650
673
  queue_adapter.is_a?(ActiveJob::QueueAdapters::TestAdapter)
651
674
  end
data/lib/active_job.rb CHANGED
@@ -39,6 +39,7 @@ module ActiveJob
39
39
  autoload :Arguments
40
40
  autoload :DeserializationError, "active_job/arguments"
41
41
  autoload :SerializationError, "active_job/arguments"
42
+ autoload :EnqueueAfterTransactionCommit
42
43
 
43
44
  eager_autoload do
44
45
  autoload :Serializers
@@ -48,16 +49,20 @@ module ActiveJob
48
49
  autoload :TestCase
49
50
  autoload :TestHelper
50
51
 
51
- ##
52
- # :singleton-method:
53
- # If false, \Rails will preserve the legacy serialization of BigDecimal job arguments as Strings.
54
- # If true, \Rails will use the new BigDecimalSerializer to (de)serialize BigDecimal losslessly.
55
- # Legacy serialization will be removed in \Rails 7.2, along with this config.
56
- singleton_class.attr_accessor :use_big_decimal_serializer
57
- self.use_big_decimal_serializer = false
52
+ def self.use_big_decimal_serializer
53
+ ActiveJob.deprecator.warn <<-WARNING.squish
54
+ Rails.application.config.active_job.use_big_decimal_serializer is deprecated and will be removed in Rails 8.0.
55
+ WARNING
56
+ end
57
+
58
+ def self.use_big_decimal_serializer=(value)
59
+ ActiveJob.deprecator.warn <<-WARNING.squish
60
+ Rails.application.config.active_job.use_big_decimal_serializer is deprecated and will be removed in Rails 8.0.
61
+ WARNING
62
+ end
58
63
 
59
64
  ##
60
- # :singleton-method:
65
+ # :singleton-method: verbose_enqueue_logs
61
66
  #
62
67
  # Specifies if the methods calling background job enqueue should be logged below
63
68
  # their relevant enqueue log lines. Defaults to false.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activejob
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.5.1
4
+ version: 7.2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 7.1.5.1
19
+ version: 7.2.2.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 7.1.5.1
26
+ version: 7.2.2.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: globalid
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -54,6 +54,7 @@ files:
54
54
  - lib/active_job/configured_job.rb
55
55
  - lib/active_job/core.rb
56
56
  - lib/active_job/deprecator.rb
57
+ - lib/active_job/enqueue_after_transaction_commit.rb
57
58
  - lib/active_job/enqueuing.rb
58
59
  - lib/active_job/exceptions.rb
59
60
  - lib/active_job/execution.rb
@@ -63,6 +64,7 @@ files:
63
64
  - lib/active_job/logging.rb
64
65
  - lib/active_job/queue_adapter.rb
65
66
  - lib/active_job/queue_adapters.rb
67
+ - lib/active_job/queue_adapters/abstract_adapter.rb
66
68
  - lib/active_job/queue_adapters/async_adapter.rb
67
69
  - lib/active_job/queue_adapters/backburner_adapter.rb
68
70
  - lib/active_job/queue_adapters/delayed_job_adapter.rb
@@ -102,10 +104,10 @@ licenses:
102
104
  - MIT
103
105
  metadata:
104
106
  bug_tracker_uri: https://github.com/rails/rails/issues
105
- changelog_uri: https://github.com/rails/rails/blob/v7.1.5.1/activejob/CHANGELOG.md
106
- documentation_uri: https://api.rubyonrails.org/v7.1.5.1/
107
+ changelog_uri: https://github.com/rails/rails/blob/v7.2.2.1/activejob/CHANGELOG.md
108
+ documentation_uri: https://api.rubyonrails.org/v7.2.2.1/
107
109
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
108
- source_code_uri: https://github.com/rails/rails/tree/v7.1.5.1/activejob
110
+ source_code_uri: https://github.com/rails/rails/tree/v7.2.2.1/activejob
109
111
  rubygems_mfa_required: 'true'
110
112
  post_install_message:
111
113
  rdoc_options: []
@@ -115,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
117
  requirements:
116
118
  - - ">="
117
119
  - !ruby/object:Gem::Version
118
- version: 2.7.0
120
+ version: 3.1.0
119
121
  required_rubygems_version: !ruby/object:Gem::Requirement
120
122
  requirements:
121
123
  - - ">="