activejob 6.0.6.1 → 6.1.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/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)
|