activejob 6.1.7.7 → 7.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +36 -242
  3. data/MIT-LICENSE +2 -1
  4. data/README.md +3 -3
  5. data/lib/active_job/arguments.rb +10 -15
  6. data/lib/active_job/base.rb +2 -2
  7. data/lib/active_job/configured_job.rb +5 -7
  8. data/lib/active_job/core.rb +11 -1
  9. data/lib/active_job/enqueuing.rb +22 -9
  10. data/lib/active_job/exceptions.rb +4 -2
  11. data/lib/active_job/execution.rb +12 -8
  12. data/lib/active_job/gem_version.rb +4 -4
  13. data/lib/active_job/instrumentation.rb +9 -5
  14. data/lib/active_job/log_subscriber.rb +1 -1
  15. data/lib/active_job/logging.rb +8 -5
  16. data/lib/active_job/query_tags.rb +16 -0
  17. data/lib/active_job/queue_adapter.rb +1 -1
  18. data/lib/active_job/queue_adapters/async_adapter.rb +6 -6
  19. data/lib/active_job/queue_adapters/backburner_adapter.rb +3 -3
  20. data/lib/active_job/queue_adapters/delayed_job_adapter.rb +14 -4
  21. data/lib/active_job/queue_adapters/inline_adapter.rb +2 -2
  22. data/lib/active_job/queue_adapters/que_adapter.rb +3 -3
  23. data/lib/active_job/queue_adapters/queue_classic_adapter.rb +3 -3
  24. data/lib/active_job/queue_adapters/resque_adapter.rb +3 -3
  25. data/lib/active_job/queue_adapters/sidekiq_adapter.rb +3 -3
  26. data/lib/active_job/queue_adapters/sneakers_adapter.rb +3 -3
  27. data/lib/active_job/queue_adapters/sucker_punch_adapter.rb +3 -3
  28. data/lib/active_job/queue_adapters/test_adapter.rb +3 -2
  29. data/lib/active_job/queue_name.rb +1 -1
  30. data/lib/active_job/railtie.rb +26 -1
  31. data/lib/active_job/serializers/range_serializer.rb +23 -0
  32. data/lib/active_job/serializers.rb +3 -1
  33. data/lib/active_job/test_helper.rb +7 -7
  34. data/lib/active_job/timezones.rb +1 -1
  35. data/lib/active_job/translation.rb +1 -1
  36. data/lib/active_job.rb +2 -1
  37. metadata +16 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6c681e702ae8897bbf9e8d0edab87b2f9f8b1da0c4df1b85d3773d78dc9bbbf
4
- data.tar.gz: 64c2592cf66389e2f34bf20fbf946cd42142018368e73c36b8814a719bc40c6c
3
+ metadata.gz: 34ec9d3dc4bb88ce5c06f50a5efb7d34fb383b38088a400a1dc307329be429a9
4
+ data.tar.gz: 8d2a9541a56b633fabb47adbf164d6568f7487ab07f5749e96917320c5f66b0a
5
5
  SHA512:
6
- metadata.gz: 0eb4778f3f8565ef62ab91e21c4ca43678c1c9aa5379ba2ea9905381df237a09feb5770a94cb0079fd492d7027a725767610581a696d27baa2e4e59072baccf5
7
- data.tar.gz: 27fc5b38d923ef2640212d1f4f7451efa99d2e4187403a20c6c2ad4b00e0fd1a161bea9aa3ba74401192d72101c579ce0a1b8068f188e110b4269b24d2f93b67
6
+ metadata.gz: 52b3116d2eba23f548e2af97a90a31fb544a0bb8c53e2642b6d0d8cdc03d419dc2de8bac6243b409b32d15fbf1af4da42e356f19df765d6b708b5b55b7283bb9
7
+ data.tar.gz: b8f3195cf56348deed886b834fe67a9f036b931f7b93c386888411d6aabc84467d87fc0a56ac2263b9d21df0e8294a3438d80e0748099ec1bd28bfcd4940c96e
data/CHANGELOG.md CHANGED
@@ -1,266 +1,60 @@
1
- ## Rails 6.1.7.7 (February 21, 2024) ##
1
+ ## Rails 7.0.0.alpha1 (September 15, 2021) ##
2
2
 
3
- * No changes.
3
+ * Allow a job to retry indefinitely
4
4
 
5
+ The `attempts` parameter of the `retry_on` method now accepts the
6
+ symbol reference `:unlimited` in addition to a specific number of retry
7
+ attempts to allow a developer to specify that a job should retry
8
+ forever until it succeeds.
5
9
 
6
- ## Rails 6.1.7.6 (August 22, 2023) ##
10
+ class MyJob < ActiveJob::Base
11
+ retry_on(AlwaysRetryException, attempts: :unlimited)
7
12
 
8
- * No changes.
9
-
10
-
11
- ## Rails 6.1.7.5 (August 22, 2023) ##
12
-
13
- * No changes.
14
-
15
-
16
- ## Rails 6.1.7.4 (June 26, 2023) ##
17
-
18
- * No changes.
19
-
20
-
21
- ## Rails 6.1.7.3 (March 13, 2023) ##
22
-
23
- * No changes.
24
-
25
-
26
- ## Rails 6.1.7.2 (January 24, 2023) ##
27
-
28
- * No changes.
29
-
30
-
31
- ## Rails 6.1.7.1 (January 17, 2023) ##
32
-
33
- * No changes.
34
-
35
-
36
- ## Rails 6.1.7 (September 09, 2022) ##
37
-
38
- * No changes.
39
-
40
-
41
- ## Rails 6.1.6.1 (July 12, 2022) ##
42
-
43
- * No changes.
44
-
45
-
46
- ## Rails 6.1.6 (May 09, 2022) ##
47
-
48
- * No changes.
49
-
50
-
51
- ## Rails 6.1.5.1 (April 26, 2022) ##
52
-
53
- * No changes.
54
-
55
-
56
- ## Rails 6.1.5 (March 09, 2022) ##
57
-
58
- * No changes.
59
-
60
-
61
- ## Rails 6.1.4.7 (March 08, 2022) ##
62
-
63
- * No changes.
64
-
65
-
66
- ## Rails 6.1.4.6 (February 11, 2022) ##
67
-
68
- * No changes.
69
-
70
-
71
- ## Rails 6.1.4.5 (February 11, 2022) ##
72
-
73
- * No changes.
74
-
75
-
76
- ## Rails 6.1.4.4 (December 15, 2021) ##
77
-
78
- * No changes.
79
-
80
-
81
- ## Rails 6.1.4.3 (December 14, 2021) ##
82
-
83
- * No changes.
84
-
85
-
86
- ## Rails 6.1.4.2 (December 14, 2021) ##
87
-
88
- * No changes.
89
-
90
-
91
- ## Rails 6.1.4.1 (August 19, 2021) ##
92
-
93
- * No changes.
94
-
95
-
96
- ## Rails 6.1.4 (June 24, 2021) ##
97
-
98
- * No changes.
99
-
100
-
101
- ## Rails 6.1.3.2 (May 05, 2021) ##
102
-
103
- * No changes.
104
-
105
-
106
- ## Rails 6.1.3.1 (March 26, 2021) ##
107
-
108
- * No changes.
109
-
110
-
111
- ## Rails 6.1.3 (February 17, 2021) ##
112
-
113
- * No changes.
114
-
115
-
116
- ## Rails 6.1.2.1 (February 10, 2021) ##
117
-
118
- * No changes.
119
-
120
-
121
- ## Rails 6.1.2 (February 09, 2021) ##
122
-
123
- * No changes.
124
-
125
-
126
- ## Rails 6.1.1 (January 07, 2021) ##
127
-
128
- * Make `retry_job` return the job that was created.
129
-
130
- *Rafael Mendonça França*
131
-
132
- * Include `ActiveSupport::Testing::Assertions` in `ActiveJob::TestHelpers`.
133
-
134
- *Mikkel Malmberg*
135
-
136
-
137
- ## Rails 6.1.0 (December 09, 2020) ##
138
-
139
- * Recover nano precision when serializing `Time`, `TimeWithZone` and `DateTime` objects.
140
-
141
- *Alan Tan*
142
-
143
- * Deprecate `config.active_job.return_false_on_aborted_enqueue`.
144
-
145
- *Rafael Mendonça França*
146
-
147
- * Return `false` when enqueuing a job is aborted.
148
-
149
- *Rafael Mendonça França*
150
-
151
- * While using `perform_enqueued_jobs` test helper enqueued jobs must be stored for the later check with
152
- `assert_enqueued_with`.
153
-
154
- *Dmitry Polushkin*
155
-
156
- * `ActiveJob::TestCase#perform_enqueued_jobs` without a block removes performed jobs from the queue.
157
-
158
- That way the helper can be called multiple times and not perform a job invocation multiple times.
159
-
160
- ```ruby
161
- def test_jobs
162
- HelloJob.perform_later("rafael")
163
- perform_enqueued_jobs # only runs with "rafael"
164
- HelloJob.perform_later("david")
165
- perform_enqueued_jobs # only runs with "david"
166
- end
167
- ```
168
-
169
- *Étienne Barrié*
170
-
171
- * `ActiveJob::TestCase#perform_enqueued_jobs` will no longer perform retries:
172
-
173
- When calling `perform_enqueued_jobs` without a block, the adapter will
174
- now perform jobs that are **already** in the queue. Jobs that will end up in
175
- the queue afterwards won't be performed.
176
-
177
- This change only affects `perform_enqueued_jobs` when no block is given.
178
-
179
- *Edouard Chin*
180
-
181
- * Add queue name support to Que adapter.
182
-
183
- *Brad Nauta*, *Wojciech Wnętrzak*
184
-
185
- * Don't run `after_enqueue` and `after_perform` callbacks if the callback chain is halted.
186
-
187
- class MyJob < ApplicationJob
188
- before_enqueue { throw(:abort) }
189
- after_enqueue { # won't enter here anymore }
13
+ # the actual job code
190
14
  end
191
15
 
192
- `after_enqueue` and `after_perform` callbacks will no longer run if the callback chain is halted.
193
- This behaviour is a breaking change and won't take effect until Rails 7.0.
194
- To enable this behaviour in your app right now, you can add in your app's configuration file
195
- `config.active_job.skip_after_callbacks_if_terminated = true`.
16
+ *Daniel Morton*
196
17
 
197
- *Edouard Chin*
18
+ * Added possibility to check on `:priority` in test helper methods
19
+ `assert_enqueued_with` and `assert_performed_with`.
198
20
 
199
- * Fix enqueuing and performing incorrect logging message.
21
+ *Wojciech Wnętrzak*
200
22
 
201
- Jobs will no longer always log "Enqueued MyJob" or "Performed MyJob" when they actually didn't get enqueued/performed.
23
+ * OpenSSL constants are now used for Digest computations.
202
24
 
203
- ```ruby
204
- class MyJob < ApplicationJob
205
- before_enqueue { throw(:abort) }
206
- end
25
+ *Dirkjan Bussink*
207
26
 
208
- MyJob.perform_later # Will no longer log "Enqueued MyJob" since job wasn't even enqueued through adapter.
209
- ```
27
+ * Add a Serializer for the Range class.
210
28
 
211
- A new message will be logged in case a job couldn't be enqueued, either because the callback chain was halted or
212
- because an exception happened during enqueuing. (i.e. Redis is down when you try to enqueue your job)
29
+ This should allow things like `MyJob.perform_later(range: 1..100)`.
213
30
 
214
- *Edouard Chin*
31
+ * Communicate enqueue failures to callers of `perform_later`.
215
32
 
216
- * Add an option to disable logging of the job arguments when enqueuing and executing the job.
33
+ `perform_later` can now optionally take a block which will execute after
34
+ the adapter attempts to enqueue the job. The block will receive the job
35
+ instance as an argument even if the enqueue was not successful.
36
+ Additionally, `ActiveJob` adapters now have the ability to raise an
37
+ `ActiveJob::EnqueueError` which will be caught and stored in the job
38
+ instance so code attempting to enqueue jobs can inspect any raised
39
+ `EnqueueError` using the block.
217
40
 
218
- class SensitiveJob < ApplicationJob
219
- self.log_arguments = false
220
-
221
- def perform(my_sensitive_argument)
41
+ MyJob.perform_later do |job|
42
+ unless job.successfully_enqueued?
43
+ if job.enqueue_error&.message == "Redis was unavailable"
44
+ # invoke some code that will retry the job after a delay
45
+ end
222
46
  end
223
47
  end
224
48
 
225
- When dealing with sensitive arguments as password and tokens it is now possible to configure the job
226
- to not put the sensitive argument in the logs.
227
-
228
- *Rafael Mendonça França*
229
-
230
- * Changes in `queue_name_prefix` of a job no longer affects all other jobs.
231
-
232
- Fixes #37084.
233
-
234
- *Lucas Mansur*
235
-
236
- * Allow `Class` and `Module` instances to be serialized.
237
-
238
- *Kevin Deisz*
239
-
240
- * Log potential matches in `assert_enqueued_with` and `assert_performed_with`.
241
-
242
- *Gareth du Plooy*
243
-
244
- * Add `at` argument to the `perform_enqueued_jobs` test helper.
245
-
246
- *John Crepezzi*, *Eileen Uchitelle*
247
-
248
- * `assert_enqueued_with` and `assert_performed_with` can now test jobs with relative delay.
249
-
250
- *Vlado Cingel*
49
+ *Daniel Morton*
251
50
 
252
- * Add jitter to `ActiveJob::Exceptions.retry_on`.
51
+ * Don't log rescuable exceptions defined with `rescue_from`.
253
52
 
254
- `ActiveJob::Exceptions.retry_on` now uses a random amount of jitter in order to
255
- prevent the [thundering herd effect](https://en.wikipedia.org/wiki/Thundering_herd_problem). Defaults to
256
- 15% (represented as 0.15) but overridable via the `:jitter` option when using `retry_on`.
257
- Jitter is applied when an `Integer`, `ActiveSupport::Duration` or `:exponentially_longer`, is passed to the `wait` argument in `retry_on`.
53
+ *Hu Hailin*
258
54
 
259
- ```ruby
260
- retry_on(MyError, wait: :exponentially_longer, jitter: 0.30)
261
- ```
55
+ * Allow `rescue_from` to rescue all exceptions.
262
56
 
263
- *Anthony Ross*
57
+ *Adrianna Chang*, *Étienne Barrié*
264
58
 
265
59
 
266
- Please check [6-0-stable](https://github.com/rails/rails/blob/6-0-stable/activejob/CHANGELOG.md) for previous changes.
60
+ Please check [6-1-stable](https://github.com/rails/rails/blob/6-1-stable/activejob/CHANGELOG.md) for previous changes.
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2014-2022 David Heinemeier Hansson
1
+ Copyright (c) 2014-2021 David Heinemeier Hansson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -18,3 +18,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
19
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/README.md CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  Active Job is a framework for declaring jobs and making them run on a variety
4
4
  of queuing backends. These jobs can be everything from regularly scheduled
5
- clean-ups, to billing charges, to mailings. Anything that can be chopped up into
6
- small units of work and run in parallel, really.
5
+ clean-ups, to billing charges, to mailings anything that can be chopped up into
6
+ small units of work and run in parallel.
7
7
 
8
8
  It also serves as the backend for Action Mailer's #deliver_later functionality
9
9
  that makes it easy to turn any mailing into a job for running later. That's
10
10
  one of the most common jobs in a modern web application: sending emails outside
11
- of the request-response cycle, so the user doesn't have to wait on it.
11
+ the request-response cycle, so the user doesn't have to wait on it.
12
12
 
13
13
  The main point is to ensure that all Rails apps will have a job infrastructure
14
14
  in place, even if it's in the form of an "immediate runner". We can then have
@@ -7,7 +7,7 @@ module ActiveJob
7
7
  #
8
8
  # Wraps the original exception raised as +cause+.
9
9
  class DeserializationError < StandardError
10
- def initialize #:nodoc:
10
+ def initialize # :nodoc:
11
11
  super("Error while trying to deserialize arguments: #{$!.message}")
12
12
  set_backtrace $!.backtrace
13
13
  end
@@ -17,8 +17,8 @@ module ActiveJob
17
17
  # currently support String, Integer, Float, NilClass, TrueClass, FalseClass,
18
18
  # BigDecimal, Symbol, Date, Time, DateTime, ActiveSupport::TimeWithZone,
19
19
  # ActiveSupport::Duration, Hash, ActiveSupport::HashWithIndifferentAccess,
20
- # Array or GlobalID::Identification instances, although this can be extended
21
- # by adding custom serializers.
20
+ # Array, Range or GlobalID::Identification instances, although this can be
21
+ # extended by adding custom serializers.
22
22
  # Raised if you set the key for a Hash something else than a string or
23
23
  # a symbol. Also raised when trying to serialize an object which can't be
24
24
  # identified with a GlobalID - such as an unpersisted Active Record model.
@@ -73,24 +73,19 @@ module ActiveJob
73
73
  using Module.new {
74
74
  refine Hash do
75
75
  class << Hash
76
- if RUBY_VERSION >= "2.7"
77
- def ruby2_keywords_hash?(hash)
78
- !new(*[hash]).default.equal?(hash)
79
- end
80
- else
81
- def ruby2_keywords_hash?(hash)
82
- false
83
- end
76
+ def ruby2_keywords_hash?(hash)
77
+ !new(*[hash]).default.equal?(hash)
84
78
  end
85
79
 
86
80
  def ruby2_keywords_hash(hash)
87
81
  _ruby2_keywords_hash(**hash)
88
82
  end
89
83
 
90
- private def _ruby2_keywords_hash(*args)
91
- args.last
92
- end
93
- ruby2_keywords(:_ruby2_keywords_hash) if respond_to?(:ruby2_keywords, true)
84
+ private
85
+ def _ruby2_keywords_hash(*args)
86
+ args.last
87
+ end
88
+ ruby2_keywords(:_ruby2_keywords_hash)
94
89
  end
95
90
  end
96
91
  }
@@ -14,7 +14,7 @@ require "active_job/instrumentation"
14
14
  require "active_job/timezones"
15
15
  require "active_job/translation"
16
16
 
17
- module ActiveJob #:nodoc:
17
+ module ActiveJob # :nodoc:
18
18
  # = Active Job
19
19
  #
20
20
  # Active Job objects can be configured to work with different backend
@@ -69,8 +69,8 @@ module ActiveJob #:nodoc:
69
69
  include Execution
70
70
  include Callbacks
71
71
  include Exceptions
72
- include Logging
73
72
  include Instrumentation
73
+ include Logging
74
74
  include Timezones
75
75
  include Translation
76
76
 
@@ -1,20 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveJob
4
- class ConfiguredJob #:nodoc:
4
+ class ConfiguredJob # :nodoc:
5
5
  def initialize(job_class, options = {})
6
6
  @options = options
7
7
  @job_class = job_class
8
8
  end
9
9
 
10
- def perform_now(*args)
11
- @job_class.new(*args).perform_now
10
+ def perform_now(...)
11
+ @job_class.new(...).perform_now
12
12
  end
13
- ruby2_keywords(:perform_now) if respond_to?(:ruby2_keywords, true)
14
13
 
15
- def perform_later(*args)
16
- @job_class.new(*args).enqueue @options
14
+ def perform_later(...)
15
+ @job_class.new(...).enqueue @options
17
16
  end
18
- ruby2_keywords(:perform_later) if respond_to?(:ruby2_keywords, true)
19
17
  end
20
18
  end
@@ -43,6 +43,16 @@ module ActiveJob
43
43
  # Track when a job was enqueued
44
44
  attr_accessor :enqueued_at
45
45
 
46
+ # Track whether the adapter received the job successfully.
47
+ attr_writer :successfully_enqueued # :nodoc:
48
+
49
+ def successfully_enqueued?
50
+ @successfully_enqueued
51
+ end
52
+
53
+ # Track any exceptions raised by the backend so callers can inspect the errors.
54
+ attr_accessor :enqueue_error
55
+
46
56
  # These methods will be included into any Active Job object, adding
47
57
  # helpers for de/serialization and creation of job instances.
48
58
  module ClassMethods
@@ -87,7 +97,7 @@ module ActiveJob
87
97
  @exception_executions = {}
88
98
  @timezone = Time.zone&.name
89
99
  end
90
- ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
100
+ ruby2_keywords(:initialize)
91
101
 
92
102
  # Returns a hash with the job data that can safely be passed to the
93
103
  # queuing adapter.
@@ -4,6 +4,11 @@ require "active_job/arguments"
4
4
 
5
5
  module ActiveJob
6
6
  # Provides behavior for enqueuing jobs.
7
+
8
+ # Can be raised by adapters if they wish to communicate to the caller a reason
9
+ # why the adapter was unexpectedly unable to enqueue a job.
10
+ class EnqueueError < StandardError; end
11
+
7
12
  module Enqueuing
8
13
  extend ActiveSupport::Concern
9
14
 
@@ -12,22 +17,28 @@ module ActiveJob
12
17
  # Push a job onto the queue. By default the arguments must be either String,
13
18
  # Integer, Float, NilClass, TrueClass, FalseClass, BigDecimal, Symbol, Date,
14
19
  # Time, DateTime, ActiveSupport::TimeWithZone, ActiveSupport::Duration,
15
- # Hash, ActiveSupport::HashWithIndifferentAccess, Array or
20
+ # Hash, ActiveSupport::HashWithIndifferentAccess, Array, Range or
16
21
  # GlobalID::Identification instances, although this can be extended by adding
17
22
  # custom serializers.
18
23
  #
19
24
  # Returns an instance of the job class queued with arguments available in
20
- # Job#arguments.
21
- def perform_later(*args)
22
- job_or_instantiate(*args).enqueue
25
+ # Job#arguments or false if the enqueue did not succeed.
26
+ #
27
+ # After the attempted enqueue, the job will be yielded to an optional block.
28
+ def perform_later(...)
29
+ job = job_or_instantiate(...)
30
+ enqueue_result = job.enqueue
31
+
32
+ yield job if block_given?
33
+
34
+ enqueue_result
23
35
  end
24
- ruby2_keywords(:perform_later) if respond_to?(:ruby2_keywords, true)
25
36
 
26
37
  private
27
38
  def job_or_instantiate(*args) # :doc:
28
39
  args.first.is_a?(self) ? args.first : new(*args)
29
40
  end
30
- ruby2_keywords(:job_or_instantiate) if respond_to?(:ruby2_keywords, true)
41
+ ruby2_keywords(:job_or_instantiate)
31
42
  end
32
43
 
33
44
  # Enqueues the job to be performed by the queue adapter.
@@ -50,7 +61,7 @@ module ActiveJob
50
61
  self.scheduled_at = options[:wait_until].to_f if options[:wait_until]
51
62
  self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue]
52
63
  self.priority = options[:priority].to_i if options[:priority]
53
- successfully_enqueued = false
64
+ self.successfully_enqueued = false
54
65
 
55
66
  run_callbacks :enqueue do
56
67
  if scheduled_at
@@ -59,10 +70,12 @@ module ActiveJob
59
70
  queue_adapter.enqueue self
60
71
  end
61
72
 
62
- successfully_enqueued = true
73
+ self.successfully_enqueued = true
74
+ rescue EnqueueError => e
75
+ self.enqueue_error = e
63
76
  end
64
77
 
65
- if successfully_enqueued
78
+ if successfully_enqueued?
66
79
  self
67
80
  else
68
81
  false
@@ -25,7 +25,8 @@ module ActiveJob
25
25
  # as a computing proc that takes the number of executions so far as an argument, or as a symbol reference of
26
26
  # <tt>:exponentially_longer</tt>, which applies the wait algorithm of <tt>((executions**4) + (Kernel.rand * (executions**4) * jitter)) + 2</tt>
27
27
  # (first wait ~3s, then ~18s, then ~83s, etc)
28
- # * <tt>:attempts</tt> - Re-enqueues the job the specified number of times (default: 5 attempts)
28
+ # * <tt>:attempts</tt> - Re-enqueues the job the specified number of times (default: 5 attempts) or a symbol reference of <tt>:unlimited</tt>
29
+ # to retry the job until it succeeds
29
30
  # * <tt>:queue</tt> - Re-enqueues the job on a different queue
30
31
  # * <tt>:priority</tt> - Re-enqueues the job with a different priority
31
32
  # * <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)
@@ -35,6 +36,7 @@ module ActiveJob
35
36
  # class RemoteServiceJob < ActiveJob::Base
36
37
  # retry_on CustomAppException # defaults to ~3s wait, 5 attempts
37
38
  # retry_on AnotherCustomAppException, wait: ->(executions) { executions * 2 }
39
+ # retry_on CustomInfrastructureException, wait: 5.minutes, attempts: :unlimited
38
40
  #
39
41
  # retry_on ActiveRecord::Deadlocked, wait: 5.seconds, attempts: 3
40
42
  # retry_on Net::OpenTimeout, Timeout::Error, wait: :exponentially_longer, attempts: 10 # retries at most 10 times for Net::OpenTimeout and Timeout::Error combined
@@ -56,7 +58,7 @@ module ActiveJob
56
58
  def retry_on(*exceptions, wait: 3.seconds, attempts: 5, queue: nil, priority: nil, jitter: JITTER_DEFAULT)
57
59
  rescue_from(*exceptions) do |error|
58
60
  executions = executions_for(exceptions)
59
- if executions < attempts
61
+ if attempts == :unlimited || executions < attempts
60
62
  retry_job wait: determine_delay(seconds_or_duration_or_algorithm: wait, executions: executions, jitter: jitter), queue: queue, priority: priority, error: error
61
63
  else
62
64
  if block_given?
@@ -14,12 +14,11 @@ module ActiveJob
14
14
  #
15
15
  # MyJob.perform_now("mike")
16
16
  #
17
- def perform_now(*args)
18
- job_or_instantiate(*args).perform_now
17
+ def perform_now(...)
18
+ job_or_instantiate(...).perform_now
19
19
  end
20
- ruby2_keywords(:perform_now) if respond_to?(:ruby2_keywords, true)
21
20
 
22
- def execute(job_data) #:nodoc:
21
+ def execute(job_data) # :nodoc:
23
22
  ActiveJob::Callbacks.run_callbacks(:execute) do
24
23
  job = deserialize(job_data)
25
24
  job.perform_now
@@ -44,15 +43,20 @@ module ActiveJob
44
43
 
45
44
  deserialize_arguments_if_needed
46
45
 
47
- run_callbacks :perform do
48
- perform(*arguments)
49
- end
50
- rescue => exception
46
+ _perform_job
47
+ rescue Exception => exception
51
48
  rescue_with_handler(exception) || raise
52
49
  end
53
50
 
54
51
  def perform(*)
55
52
  fail NotImplementedError
56
53
  end
54
+
55
+ private
56
+ def _perform_job
57
+ run_callbacks :perform do
58
+ perform(*arguments)
59
+ end
60
+ end
57
61
  end
58
62
  end
@@ -7,10 +7,10 @@ module ActiveJob
7
7
  end
8
8
 
9
9
  module VERSION
10
- MAJOR = 6
11
- MINOR = 1
12
- TINY = 7
13
- PRE = "7"
10
+ MAJOR = 7
11
+ MINOR = 0
12
+ TINY = 0
13
+ PRE = "alpha1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
@@ -1,21 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveJob
4
- module Instrumentation #:nodoc:
4
+ module Instrumentation # :nodoc:
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
8
  around_enqueue do |_, block|
9
9
  scheduled_at ? instrument(:enqueue_at, &block) : instrument(:enqueue, &block)
10
10
  end
11
+ end
11
12
 
12
- around_perform do |_, block|
13
- instrument :perform_start
14
- instrument :perform, &block
15
- end
13
+ def perform_now
14
+ instrument(:perform) { super }
16
15
  end
17
16
 
18
17
  private
18
+ def _perform_job
19
+ instrument(:perform_start)
20
+ super
21
+ end
22
+
19
23
  def instrument(operation, payload = {}, &block)
20
24
  enhanced_block = ->(event_payload) do
21
25
  value = block.call if block
@@ -4,7 +4,7 @@ require "active_support/core_ext/string/filters"
4
4
  require "active_support/log_subscriber"
5
5
 
6
6
  module ActiveJob
7
- class LogSubscriber < ActiveSupport::LogSubscriber #:nodoc:
7
+ class LogSubscriber < ActiveSupport::LogSubscriber # :nodoc:
8
8
  def enqueue(event)
9
9
  job = event.payload[:job]
10
10
  ex = event.payload[:exception_object]