activejob 6.0.6.1 → 6.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +74 -237
- data/MIT-LICENSE +1 -1
- data/README.md +2 -4
- data/lib/active_job/base.rb +3 -0
- data/lib/active_job/callbacks.rb +44 -4
- data/lib/active_job/core.rb +2 -2
- data/lib/active_job/enqueuing.rb +3 -13
- data/lib/active_job/exceptions.rb +29 -20
- data/lib/active_job/execution.rb +9 -1
- data/lib/active_job/gem_version.rb +3 -3
- data/lib/active_job/instrumentation.rb +37 -0
- data/lib/active_job/log_subscriber.rb +140 -0
- data/lib/active_job/logging.rb +3 -132
- data/lib/active_job/queue_adapter.rb +3 -0
- data/lib/active_job/queue_adapters/inline_adapter.rb +1 -1
- data/lib/active_job/queue_adapters/sucker_punch_adapter.rb +1 -1
- data/lib/active_job/queue_adapters/test_adapter.rb +6 -2
- data/lib/active_job/queue_adapters.rb +5 -1
- data/lib/active_job/queue_name.rb +2 -2
- data/lib/active_job/railtie.rb +4 -0
- data/lib/active_job/serializers/date_time_serializer.rb +1 -5
- data/lib/active_job/serializers/module_serializer.rb +20 -0
- data/lib/active_job/serializers/object_serializer.rb +1 -1
- data/lib/active_job/serializers/time_object_serializer.rb +13 -0
- data/lib/active_job/serializers/time_serializer.rb +1 -5
- data/lib/active_job/serializers/time_with_zone_serializer.rb +1 -5
- data/lib/active_job/serializers.rb +4 -1
- data/lib/active_job/test_helper.rb +79 -80
- data/lib/active_job.rb +1 -1
- metadata +17 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc9b631f7b43e77aa14e8fb65525b51ad82f92f5b0046d15d44c2e5f2429a2aa
|
4
|
+
data.tar.gz: a2e8afb6e5295337e82c0f0c3de726cbe11dcedba0f2f34c6c4323170a74dc13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b30c316861f1ae07c363df9184ef9a306d796756429d11978166b3864263cc72ff521c6d27093e17f0e2e850b6921c3dd39702646d6f5b7a5a198221d1e68f4f
|
7
|
+
data.tar.gz: 99ed04c52a31748e94edd687fe93a48de660e44d29b5645597a278a97450405f57c28b92d69b98cf0f3ded97711952a58b700b9f90e2ad8dac5148b843920b17
|
data/CHANGELOG.md
CHANGED
@@ -1,293 +1,130 @@
|
|
1
|
-
## Rails 6.0.
|
1
|
+
## Rails 6.1.0.rc1 (November 02, 2020) ##
|
2
2
|
|
3
|
-
*
|
3
|
+
* Recover nano precision when serializing `Time`, `TimeWithZone` and `DateTime` objects.
|
4
4
|
|
5
|
+
*Alan Tan*
|
5
6
|
|
6
|
-
|
7
|
+
* Deprecate `config.active_job.return_false_on_aborted_enqueue`.
|
7
8
|
|
8
|
-
*
|
9
|
+
*Rafael Mendonça França*
|
9
10
|
|
11
|
+
* Return `false` when enqueuing a job is aborted.
|
10
12
|
|
11
|
-
|
12
|
-
|
13
|
-
* No changes.
|
14
|
-
|
15
|
-
|
16
|
-
## Rails 6.0.5 (May 09, 2022) ##
|
17
|
-
|
18
|
-
* No changes.
|
19
|
-
|
20
|
-
|
21
|
-
## Rails 6.0.4.8 (April 26, 2022) ##
|
22
|
-
|
23
|
-
* No changes.
|
24
|
-
|
25
|
-
|
26
|
-
## Rails 6.0.4.7 (March 08, 2022) ##
|
27
|
-
|
28
|
-
* No changes.
|
29
|
-
|
30
|
-
|
31
|
-
## Rails 6.0.4.6 (February 11, 2022) ##
|
32
|
-
|
33
|
-
* No changes.
|
34
|
-
|
35
|
-
|
36
|
-
## Rails 6.0.4.5 (February 11, 2022) ##
|
37
|
-
|
38
|
-
* No changes.
|
39
|
-
|
40
|
-
|
41
|
-
## Rails 6.0.4.4 (December 15, 2021) ##
|
42
|
-
|
43
|
-
* No changes.
|
44
|
-
|
45
|
-
|
46
|
-
## Rails 6.0.4.3 (December 14, 2021) ##
|
47
|
-
|
48
|
-
* No changes.
|
49
|
-
|
50
|
-
|
51
|
-
## Rails 6.0.4.2 (December 14, 2021) ##
|
52
|
-
|
53
|
-
* No changes.
|
54
|
-
|
55
|
-
|
56
|
-
## Rails 6.0.4.1 (August 19, 2021) ##
|
57
|
-
|
58
|
-
* No changes.
|
59
|
-
|
60
|
-
|
61
|
-
## Rails 6.0.4 (June 15, 2021) ##
|
62
|
-
|
63
|
-
* No changes.
|
64
|
-
|
65
|
-
|
66
|
-
## Rails 6.0.3.7 (May 05, 2021) ##
|
67
|
-
|
68
|
-
* No changes.
|
69
|
-
|
70
|
-
|
71
|
-
## Rails 6.0.3.6 (March 26, 2021) ##
|
72
|
-
|
73
|
-
* No changes.
|
74
|
-
|
75
|
-
|
76
|
-
## Rails 6.0.3.5 (February 10, 2021) ##
|
77
|
-
|
78
|
-
* No changes.
|
79
|
-
|
80
|
-
|
81
|
-
## Rails 6.0.3.4 (October 07, 2020) ##
|
82
|
-
|
83
|
-
* No changes.
|
84
|
-
|
85
|
-
|
86
|
-
## Rails 6.0.3.3 (September 09, 2020) ##
|
87
|
-
|
88
|
-
* No changes.
|
89
|
-
|
90
|
-
|
91
|
-
## Rails 6.0.3.2 (June 17, 2020) ##
|
92
|
-
|
93
|
-
* No changes.
|
94
|
-
|
95
|
-
|
96
|
-
## Rails 6.0.3.1 (May 18, 2020) ##
|
97
|
-
|
98
|
-
* No changes.
|
99
|
-
|
100
|
-
|
101
|
-
## Rails 6.0.3 (May 06, 2020) ##
|
13
|
+
*Rafael Mendonça França*
|
102
14
|
|
103
15
|
* While using `perform_enqueued_jobs` test helper enqueued jobs must be stored for the later check with
|
104
16
|
`assert_enqueued_with`.
|
105
17
|
|
106
18
|
*Dmitry Polushkin*
|
107
19
|
|
108
|
-
*
|
109
|
-
|
110
|
-
*Brad Nauta*, *Wojciech Wnętrzak*
|
111
|
-
|
112
|
-
|
113
|
-
## Rails 6.0.2.2 (March 19, 2020) ##
|
20
|
+
* `ActiveJob::TestCase#perform_enqueued_jobs` without a block removes performed jobs from the queue.
|
114
21
|
|
115
|
-
|
22
|
+
That way the helper can be called multiple times and not perform a job invocation multiple times.
|
116
23
|
|
24
|
+
```ruby
|
25
|
+
def test_jobs
|
26
|
+
HelloJob.perform_later("rafael")
|
27
|
+
perform_enqueued_jobs # only runs with "rafael"
|
28
|
+
HelloJob.perform_later("david")
|
29
|
+
perform_enqueued_jobs # only runs with "david"
|
30
|
+
end
|
31
|
+
```
|
117
32
|
|
118
|
-
|
119
|
-
|
120
|
-
* No changes.
|
121
|
-
|
122
|
-
|
123
|
-
## Rails 6.0.2 (December 13, 2019) ##
|
124
|
-
|
125
|
-
* Allow Sidekiq access to the underlying job class.
|
126
|
-
|
127
|
-
By having access to the Active Job class, Sidekiq can get access to any `sidekiq_options` which
|
128
|
-
have been set on that Active Job type and serialize those options into Redis.
|
129
|
-
|
130
|
-
https://github.com/mperham/sidekiq/blob/master/Changes.md#60
|
131
|
-
|
132
|
-
*Mike Perham*
|
133
|
-
|
134
|
-
|
135
|
-
## Rails 6.0.1 (November 5, 2019) ##
|
136
|
-
|
137
|
-
* No changes.
|
138
|
-
|
139
|
-
|
140
|
-
## Rails 6.0.0 (August 16, 2019) ##
|
141
|
-
|
142
|
-
* `assert_enqueued_with` and `assert_performed_with` can now test jobs with relative delay.
|
143
|
-
|
144
|
-
*Vlado Cingel*
|
145
|
-
|
146
|
-
|
147
|
-
## Rails 6.0.0.rc2 (July 22, 2019) ##
|
148
|
-
|
149
|
-
* No changes.
|
150
|
-
|
151
|
-
|
152
|
-
## Rails 6.0.0.rc1 (April 24, 2019) ##
|
153
|
-
|
154
|
-
* Use individual execution counters when calculating retry delay.
|
155
|
-
|
156
|
-
*Patrik Bóna*
|
157
|
-
|
158
|
-
* Make job argument assertions with `Time`, `ActiveSupport::TimeWithZone`, and `DateTime` work by dropping microseconds. Microsecond precision is lost during serialization.
|
159
|
-
|
160
|
-
*Gannon McGibbon*
|
161
|
-
|
162
|
-
|
163
|
-
## Rails 6.0.0.beta3 (March 11, 2019) ##
|
164
|
-
|
165
|
-
* No changes.
|
166
|
-
|
167
|
-
|
168
|
-
## Rails 6.0.0.beta2 (February 25, 2019) ##
|
169
|
-
|
170
|
-
* No changes.
|
33
|
+
*Étienne Barrié*
|
171
34
|
|
35
|
+
* `ActiveJob::TestCase#perform_enqueued_jobs` will no longer perform retries:
|
172
36
|
|
173
|
-
|
37
|
+
When calling `perform_enqueued_jobs` without a block, the adapter will
|
38
|
+
now perform jobs that are **already** in the queue. Jobs that will end up in
|
39
|
+
the queue afterwards won't be performed.
|
174
40
|
|
175
|
-
|
41
|
+
This change only affects `perform_enqueued_jobs` when no block is given.
|
176
42
|
|
177
|
-
|
178
|
-
`config.active_job.return_false_on_aborted_enqueue`.
|
43
|
+
*Edouard Chin*
|
179
44
|
|
180
|
-
|
45
|
+
* Add queue name support to Que adapter.
|
181
46
|
|
182
|
-
*
|
47
|
+
*Brad Nauta*, *Wojciech Wnętrzak*
|
183
48
|
|
184
|
-
|
185
|
-
shared between all executions of a job.
|
49
|
+
* Don't run `after_enqueue` and `after_perform` callbacks if the callback chain is halted.
|
186
50
|
|
187
|
-
|
51
|
+
class MyJob < ApplicationJob
|
52
|
+
before_enqueue { throw(:abort) }
|
53
|
+
after_enqueue { # won't enter here anymore }
|
54
|
+
end
|
188
55
|
|
189
|
-
|
190
|
-
|
56
|
+
`after_enqueue` and `after_perform` callbacks will no longer run if the callback chain is halted.
|
57
|
+
This behaviour is a breaking change and won't take effect until Rails 6.2.
|
58
|
+
To enable this behaviour in your app right now, you can add in your app's configuration file
|
59
|
+
`config.active_job.skip_after_callbacks_if_terminated = true`.
|
191
60
|
|
192
61
|
*Edouard Chin*
|
193
62
|
|
194
|
-
*
|
63
|
+
* Fix enqueuing and performing incorrect logging message.
|
195
64
|
|
196
|
-
|
65
|
+
Jobs will no longer always log "Enqueued MyJob" or "Performed MyJob" when they actually didn't get enqueued/performed.
|
197
66
|
|
198
|
-
|
199
|
-
|
67
|
+
```ruby
|
68
|
+
class MyJob < ApplicationJob
|
69
|
+
before_enqueue { throw(:abort) }
|
70
|
+
end
|
200
71
|
|
201
|
-
|
72
|
+
MyJob.perform_later # Will no longer log "Enqueued MyJob" since job wasn't even enqueued through adapter.
|
73
|
+
```
|
202
74
|
|
203
|
-
|
204
|
-
|
205
|
-
matches your expectations.
|
75
|
+
A new message will be logged in case a job couldn't be enqueued, either because the callback chain was halted or
|
76
|
+
because an exception happened during enqueing. (i.e. Redis is down when you try to enqueue your job)
|
206
77
|
|
207
78
|
*Edouard Chin*
|
208
79
|
|
209
|
-
*
|
80
|
+
* Add an option to disable logging of the job arguments when enqueuing and executing the job.
|
210
81
|
|
211
|
-
|
82
|
+
class SensitiveJob < ApplicationJob
|
83
|
+
self.log_arguments = false
|
212
84
|
|
213
|
-
|
85
|
+
def perform(my_sensitive_argument)
|
86
|
+
end
|
87
|
+
end
|
214
88
|
|
215
|
-
|
89
|
+
When dealing with sensitive arguments as password and tokens it is now possible to configure the job
|
90
|
+
to not put the sensitive argument in the logs.
|
216
91
|
|
217
|
-
*
|
92
|
+
*Rafael Mendonça França*
|
218
93
|
|
219
|
-
|
94
|
+
* Changes in `queue_name_prefix` of a job no longer affects all other jobs.
|
220
95
|
|
221
|
-
|
222
|
-
without a block should respect passed `:except`, `:only`, and `:queue` options.
|
96
|
+
Fixes #37084.
|
223
97
|
|
224
|
-
*
|
98
|
+
*Lucas Mansur*
|
225
99
|
|
226
|
-
* Allow
|
227
|
-
|
228
|
-
*bogdanvlviv*
|
229
|
-
|
230
|
-
* Allow `perform_enqueued_jobs` to be called without a block.
|
231
|
-
|
232
|
-
Performs all of the jobs that have been enqueued up to this point in the test.
|
100
|
+
* Allow `Class` and `Module` instances to be serialized.
|
233
101
|
|
234
102
|
*Kevin Deisz*
|
235
103
|
|
236
|
-
*
|
237
|
-
|
238
|
-
Improves timing accuracy over the old after callback by including
|
239
|
-
time spent writing to the adapter's IO implementation.
|
240
|
-
|
241
|
-
*Zach Kemp*
|
242
|
-
|
243
|
-
* Allow call `assert_enqueued_with` with no block.
|
244
|
-
|
245
|
-
Example:
|
246
|
-
```
|
247
|
-
def test_assert_enqueued_with
|
248
|
-
MyJob.perform_later(1,2,3)
|
249
|
-
assert_enqueued_with(job: MyJob, args: [1,2,3], queue: 'low')
|
250
|
-
|
251
|
-
MyJob.set(wait_until: Date.tomorrow.noon).perform_later
|
252
|
-
assert_enqueued_with(job: MyJob, at: Date.tomorrow.noon)
|
253
|
-
end
|
254
|
-
```
|
255
|
-
|
256
|
-
*bogdanvlviv*
|
257
|
-
|
258
|
-
* Allow passing multiple exceptions to `retry_on`, and `discard_on`.
|
259
|
-
|
260
|
-
*George Claghorn*
|
104
|
+
* Log potential matches in `assert_enqueued_with` and `assert_performed_with`.
|
261
105
|
|
262
|
-
*
|
106
|
+
*Gareth du Plooy*
|
263
107
|
|
264
|
-
|
108
|
+
* Add `at` argument to the `perform_enqueued_jobs` test helper.
|
265
109
|
|
266
|
-
*
|
110
|
+
*John Crepezzi*, *Eileen Uchitelle*
|
267
111
|
|
268
|
-
*
|
269
|
-
|
270
|
-
Reasons are that the Qu gem wasn't compatible since Rails 5.1,
|
271
|
-
gem development was stopped in 2014 and maintainers have
|
272
|
-
confirmed its demise. See issue #32273
|
273
|
-
|
274
|
-
*Alberto Almagro*
|
275
|
-
|
276
|
-
* Add support for timezones to Active Job.
|
277
|
-
|
278
|
-
Record what was the current timezone in effect when the job was
|
279
|
-
enqueued and then restore when the job is executed in same way
|
280
|
-
that the current locale is recorded and restored.
|
112
|
+
* `assert_enqueued_with` and `assert_performed_with` can now test jobs with relative delay.
|
281
113
|
|
282
|
-
*
|
114
|
+
*Vlado Cingel*
|
283
115
|
|
284
|
-
*
|
116
|
+
* Add jitter to `ActiveJob::Exceptions.retry_on`.
|
285
117
|
|
286
|
-
|
118
|
+
`ActiveJob::Exceptions.retry_on` now uses a random amount of jitter in order to
|
119
|
+
prevent the [thundering herd effect](https://en.wikipedia.org/wiki/Thundering_herd_problem). Defaults to
|
120
|
+
15% (represented as 0.15) but overridable via the `:jitter` option when using `retry_on`.
|
121
|
+
Jitter is applied when an `Integer`, `ActiveSupport::Duration` or `:exponentially_longer`, is passed to the `wait` argument in `retry_on`.
|
287
122
|
|
288
|
-
|
123
|
+
```ruby
|
124
|
+
retry_on(MyError, wait: :exponentially_longer, jitter: 0.30)
|
125
|
+
```
|
289
126
|
|
290
|
-
*
|
127
|
+
*Anthony Ross*
|
291
128
|
|
292
129
|
|
293
|
-
Please check [
|
130
|
+
Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activejob/CHANGELOG.md) for previous changes.
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -95,9 +95,6 @@ their gem, or as a stand-alone gem. For discussion about this see the
|
|
95
95
|
following PRs: [23311](https://github.com/rails/rails/issues/23311#issuecomment-176275718),
|
96
96
|
[21406](https://github.com/rails/rails/pull/21406#issuecomment-138813484), and [#32285](https://github.com/rails/rails/pull/32285).
|
97
97
|
|
98
|
-
## Auxiliary gems
|
99
|
-
|
100
|
-
* [activejob-stats](https://github.com/seuros/activejob-stats)
|
101
98
|
|
102
99
|
## Download and installation
|
103
100
|
|
@@ -109,7 +106,8 @@ The latest version of Active Job can be installed with RubyGems:
|
|
109
106
|
|
110
107
|
Source code can be downloaded as part of the Rails project on GitHub:
|
111
108
|
|
112
|
-
* https://github.com/rails/rails/tree/
|
109
|
+
* https://github.com/rails/rails/tree/master/activejob
|
110
|
+
|
113
111
|
|
114
112
|
## License
|
115
113
|
|
data/lib/active_job/base.rb
CHANGED
@@ -8,7 +8,9 @@ require "active_job/enqueuing"
|
|
8
8
|
require "active_job/execution"
|
9
9
|
require "active_job/callbacks"
|
10
10
|
require "active_job/exceptions"
|
11
|
+
require "active_job/log_subscriber"
|
11
12
|
require "active_job/logging"
|
13
|
+
require "active_job/instrumentation"
|
12
14
|
require "active_job/timezones"
|
13
15
|
require "active_job/translation"
|
14
16
|
|
@@ -68,6 +70,7 @@ module ActiveJob #:nodoc:
|
|
68
70
|
include Callbacks
|
69
71
|
include Exceptions
|
70
72
|
include Logging
|
73
|
+
include Instrumentation
|
71
74
|
include Timezones
|
72
75
|
include Translation
|
73
76
|
|
data/lib/active_job/callbacks.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/callbacks"
|
4
|
+
require "active_support/core_ext/object/with_options"
|
5
|
+
require "active_support/core_ext/module/attribute_accessors"
|
4
6
|
|
5
7
|
module ActiveJob
|
6
8
|
# = Active Job Callbacks
|
@@ -27,16 +29,25 @@ module ActiveJob
|
|
27
29
|
end
|
28
30
|
|
29
31
|
included do
|
30
|
-
|
31
|
-
|
32
|
+
class_attribute :return_false_on_aborted_enqueue, instance_accessor: false, instance_predicate: false, default: false
|
33
|
+
singleton_class.deprecate :return_false_on_aborted_enqueue, :return_false_on_aborted_enqueue=
|
34
|
+
cattr_accessor :skip_after_callbacks_if_terminated, instance_accessor: false, default: false
|
32
35
|
|
33
|
-
|
34
|
-
|
36
|
+
with_options(skip_after_callbacks_if_terminated: skip_after_callbacks_if_terminated) do
|
37
|
+
define_callbacks :perform
|
38
|
+
define_callbacks :enqueue
|
39
|
+
end
|
35
40
|
end
|
36
41
|
|
37
42
|
# These methods will be included into any Active Job object, adding
|
38
43
|
# callbacks for +perform+ and +enqueue+ methods.
|
39
44
|
module ClassMethods
|
45
|
+
def inherited(klass)
|
46
|
+
klass.get_callbacks(:enqueue).config[:skip_after_callbacks_if_terminated] = skip_after_callbacks_if_terminated
|
47
|
+
klass.get_callbacks(:perform).config[:skip_after_callbacks_if_terminated] = skip_after_callbacks_if_terminated
|
48
|
+
super
|
49
|
+
end
|
50
|
+
|
40
51
|
# Defines a callback that will get called right before the
|
41
52
|
# job's perform method is executed.
|
42
53
|
#
|
@@ -91,6 +102,19 @@ module ActiveJob
|
|
91
102
|
# end
|
92
103
|
# end
|
93
104
|
#
|
105
|
+
# You can access the return value of the job only if the execution wasn't halted.
|
106
|
+
#
|
107
|
+
# class VideoProcessJob < ActiveJob::Base
|
108
|
+
# around_perform do |job, block|
|
109
|
+
# value = block.call
|
110
|
+
# puts value # => "Hello World!"
|
111
|
+
# end
|
112
|
+
#
|
113
|
+
# def perform
|
114
|
+
# "Hello World!"
|
115
|
+
# end
|
116
|
+
# end
|
117
|
+
#
|
94
118
|
def around_perform(*filters, &blk)
|
95
119
|
set_callback(:perform, :around, *filters, &blk)
|
96
120
|
end
|
@@ -154,5 +178,21 @@ module ActiveJob
|
|
154
178
|
set_callback(:enqueue, :around, *filters, &blk)
|
155
179
|
end
|
156
180
|
end
|
181
|
+
|
182
|
+
private
|
183
|
+
def halted_callback_hook(_filter, name) # :nodoc:
|
184
|
+
return super unless %i(enqueue perform).include?(name.to_sym)
|
185
|
+
callbacks = public_send("_#{name}_callbacks")
|
186
|
+
|
187
|
+
if !self.class.skip_after_callbacks_if_terminated && callbacks.any? { |c| c.kind == :after }
|
188
|
+
ActiveSupport::Deprecation.warn(<<~EOM)
|
189
|
+
In Rails 6.2, `after_enqueue`/`after_perform` callbacks no longer run if `before_enqueue`/`before_perform` respectively halts with `throw :abort`.
|
190
|
+
To enable this behavior, uncomment the `config.active_job.skip_after_callbacks_if_terminated` config
|
191
|
+
in the new 6.1 framework defaults initializer.
|
192
|
+
EOM
|
193
|
+
end
|
194
|
+
|
195
|
+
super
|
196
|
+
end
|
157
197
|
end
|
158
198
|
end
|
data/lib/active_job/core.rb
CHANGED
@@ -85,7 +85,7 @@ module ActiveJob
|
|
85
85
|
@priority = self.class.priority
|
86
86
|
@executions = 0
|
87
87
|
@exception_executions = {}
|
88
|
-
@timezone = Time.zone
|
88
|
+
@timezone = Time.zone&.name
|
89
89
|
end
|
90
90
|
ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
|
91
91
|
|
@@ -142,7 +142,7 @@ module ActiveJob
|
|
142
142
|
self.executions = job_data["executions"]
|
143
143
|
self.exception_executions = job_data["exception_executions"]
|
144
144
|
self.locale = job_data["locale"] || I18n.locale.to_s
|
145
|
-
self.timezone = job_data["timezone"] || Time.zone
|
145
|
+
self.timezone = job_data["timezone"] || Time.zone&.name
|
146
146
|
self.enqueued_at = job_data["enqueued_at"]
|
147
147
|
end
|
148
148
|
|
data/lib/active_job/enqueuing.rb
CHANGED
@@ -54,9 +54,9 @@ module ActiveJob
|
|
54
54
|
|
55
55
|
run_callbacks :enqueue do
|
56
56
|
if scheduled_at
|
57
|
-
|
57
|
+
queue_adapter.enqueue_at self, scheduled_at
|
58
58
|
else
|
59
|
-
|
59
|
+
queue_adapter.enqueue self
|
60
60
|
end
|
61
61
|
|
62
62
|
successfully_enqueued = true
|
@@ -65,17 +65,7 @@ module ActiveJob
|
|
65
65
|
if successfully_enqueued
|
66
66
|
self
|
67
67
|
else
|
68
|
-
|
69
|
-
false
|
70
|
-
else
|
71
|
-
ActiveSupport::Deprecation.warn(
|
72
|
-
"Rails 6.1 will return false when the enqueuing is aborted. Make sure your code doesn't depend on it" \
|
73
|
-
" returning the instance of the job and set `config.active_job.return_false_on_aborted_enqueue = true`" \
|
74
|
-
" to remove the deprecations."
|
75
|
-
)
|
76
|
-
|
77
|
-
self
|
78
|
-
end
|
68
|
+
false
|
79
69
|
end
|
80
70
|
end
|
81
71
|
end
|
@@ -7,6 +7,10 @@ module ActiveJob
|
|
7
7
|
module Exceptions
|
8
8
|
extend ActiveSupport::Concern
|
9
9
|
|
10
|
+
included do
|
11
|
+
class_attribute :retry_jitter, instance_accessor: false, instance_predicate: false, default: 0.0
|
12
|
+
end
|
13
|
+
|
10
14
|
module ClassMethods
|
11
15
|
# Catch the exception and reschedule job for re-execution after so many seconds, for a specific number of attempts.
|
12
16
|
# If the exception keeps getting raised beyond the specified number of attempts, the exception is allowed to
|
@@ -18,23 +22,25 @@ module ActiveJob
|
|
18
22
|
#
|
19
23
|
# ==== Options
|
20
24
|
# * <tt>:wait</tt> - Re-enqueues the job with a delay specified either in seconds (default: 3 seconds),
|
21
|
-
# as a computing proc that the number of executions so far as an argument, or as a symbol reference of
|
22
|
-
# <tt>:exponentially_longer</tt>, which applies the wait algorithm of <tt>(executions **
|
23
|
-
# (first wait 3s, then 18s, then 83s, etc)
|
25
|
+
# as a computing proc that takes the number of executions so far as an argument, or as a symbol reference of
|
26
|
+
# <tt>:exponentially_longer</tt>, which applies the wait algorithm of <tt>((executions**4) + (Kernel.rand * (executions**4) * jitter)) + 2</tt>
|
27
|
+
# (first wait ~3s, then ~18s, then ~83s, etc)
|
24
28
|
# * <tt>:attempts</tt> - Re-enqueues the job the specified number of times (default: 5 attempts)
|
25
29
|
# * <tt>:queue</tt> - Re-enqueues the job on a different queue
|
26
30
|
# * <tt>:priority</tt> - Re-enqueues the job with a different priority
|
31
|
+
# * <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)
|
27
32
|
#
|
28
33
|
# ==== Examples
|
29
34
|
#
|
30
35
|
# class RemoteServiceJob < ActiveJob::Base
|
31
|
-
# retry_on CustomAppException # defaults to 3s wait, 5 attempts
|
36
|
+
# retry_on CustomAppException # defaults to ~3s wait, 5 attempts
|
32
37
|
# retry_on AnotherCustomAppException, wait: ->(executions) { executions * 2 }
|
33
38
|
#
|
34
39
|
# retry_on ActiveRecord::Deadlocked, wait: 5.seconds, attempts: 3
|
35
40
|
# retry_on Net::OpenTimeout, Timeout::Error, wait: :exponentially_longer, attempts: 10 # retries at most 10 times for Net::OpenTimeout and Timeout::Error combined
|
36
41
|
# # To retry at most 10 times for each individual exception:
|
37
42
|
# # retry_on Net::OpenTimeout, wait: :exponentially_longer, attempts: 10
|
43
|
+
# # retry_on Net::ReadTimeout, wait: 5.seconds, jitter: 0.30, attempts: 10
|
38
44
|
# # retry_on Timeout::Error, wait: :exponentially_longer, attempts: 10
|
39
45
|
#
|
40
46
|
# retry_on(YetAnotherCustomAppException) do |job, error|
|
@@ -47,12 +53,11 @@ module ActiveJob
|
|
47
53
|
# # Might raise Net::OpenTimeout or Timeout::Error when the remote service is down
|
48
54
|
# end
|
49
55
|
# end
|
50
|
-
def retry_on(*exceptions, wait: 3.seconds, attempts: 5, queue: nil, priority: nil)
|
56
|
+
def retry_on(*exceptions, wait: 3.seconds, attempts: 5, queue: nil, priority: nil, jitter: JITTER_DEFAULT)
|
51
57
|
rescue_from(*exceptions) do |error|
|
52
58
|
executions = executions_for(exceptions)
|
53
|
-
|
54
59
|
if executions < attempts
|
55
|
-
retry_job wait: determine_delay(seconds_or_duration_or_algorithm: wait, executions: executions), queue: queue, priority: priority, error: error
|
60
|
+
retry_job wait: determine_delay(seconds_or_duration_or_algorithm: wait, executions: executions, jitter: jitter), queue: queue, priority: priority, error: error
|
56
61
|
else
|
57
62
|
if block_given?
|
58
63
|
instrument :retry_stopped, error: error do
|
@@ -115,22 +120,27 @@ module ActiveJob
|
|
115
120
|
# end
|
116
121
|
# end
|
117
122
|
def retry_job(options = {})
|
118
|
-
instrument :enqueue_retry,
|
123
|
+
instrument :enqueue_retry, options.slice(:error, :wait) do
|
119
124
|
enqueue options
|
120
125
|
end
|
121
126
|
end
|
122
127
|
|
123
128
|
private
|
124
|
-
|
129
|
+
JITTER_DEFAULT = Object.new
|
130
|
+
private_constant :JITTER_DEFAULT
|
131
|
+
|
132
|
+
def determine_delay(seconds_or_duration_or_algorithm:, executions:, jitter: JITTER_DEFAULT)
|
133
|
+
jitter = jitter == JITTER_DEFAULT ? self.class.retry_jitter : (jitter || 0.0)
|
134
|
+
|
125
135
|
case seconds_or_duration_or_algorithm
|
126
136
|
when :exponentially_longer
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
137
|
+
delay = executions**4
|
138
|
+
delay_jitter = determine_jitter_for_delay(delay, jitter)
|
139
|
+
delay + delay_jitter + 2
|
140
|
+
when ActiveSupport::Duration, Integer
|
141
|
+
delay = seconds_or_duration_or_algorithm.to_i
|
142
|
+
delay_jitter = determine_jitter_for_delay(delay, jitter)
|
143
|
+
delay + delay_jitter
|
134
144
|
when Proc
|
135
145
|
algorithm = seconds_or_duration_or_algorithm
|
136
146
|
algorithm.call(executions)
|
@@ -139,10 +149,9 @@ module ActiveJob
|
|
139
149
|
end
|
140
150
|
end
|
141
151
|
|
142
|
-
def
|
143
|
-
|
144
|
-
|
145
|
-
ActiveSupport::Notifications.instrument("#{name}.active_job", payload, &block)
|
152
|
+
def determine_jitter_for_delay(delay, jitter)
|
153
|
+
return 0.0 if jitter.zero?
|
154
|
+
Kernel.rand * delay * jitter
|
146
155
|
end
|
147
156
|
|
148
157
|
def executions_for(exceptions)
|