activejob 6.1.6 → 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 -192
  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: aba0689728ed5e18e29d2a9ec94adcee95be2e9c592dfc28e5fa997c993e4838
4
- data.tar.gz: 1e05515106a88bf83f153646deca0a15e7dd80c76923abf1a8a01ffe9c89745f
3
+ metadata.gz: 34ec9d3dc4bb88ce5c06f50a5efb7d34fb383b38088a400a1dc307329be429a9
4
+ data.tar.gz: 8d2a9541a56b633fabb47adbf164d6568f7487ab07f5749e96917320c5f66b0a
5
5
  SHA512:
6
- metadata.gz: c7d0c78e869461b7bb1ab9bbce1dd655d1538e3da14808a1d37036868fb828532cb987a6848ec95a93f99b4514564cd8adb1722d4d8a50de7588c6e9b77f40ca
7
- data.tar.gz: b51fe0ca5031c5a3245f0cec1b584fde53d742f5e6278f43406642649fb2fedbe040d4d5c229fdb59a411d4990196f34c09dc117ee8d1cb2090229e2da955d35
6
+ metadata.gz: 52b3116d2eba23f548e2af97a90a31fb544a0bb8c53e2642b6d0d8cdc03d419dc2de8bac6243b409b32d15fbf1af4da42e356f19df765d6b708b5b55b7283bb9
7
+ data.tar.gz: b8f3195cf56348deed886b834fe67a9f036b931f7b93c386888411d6aabc84467d87fc0a56ac2263b9d21df0e8294a3438d80e0748099ec1bd28bfcd4940c96e
data/CHANGELOG.md CHANGED
@@ -1,216 +1,60 @@
1
- ## Rails 6.1.5.1 (April 26, 2022) ##
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.5 (March 09, 2022) ##
10
+ class MyJob < ActiveJob::Base
11
+ retry_on(AlwaysRetryException, attempts: :unlimited)
7
12
 
8
- * No changes.
9
-
10
-
11
- ## Rails 6.1.4.7 (March 08, 2022) ##
12
-
13
- * No changes.
14
-
15
-
16
- ## Rails 6.1.4.6 (February 11, 2022) ##
17
-
18
- * No changes.
19
-
20
-
21
- ## Rails 6.1.4.5 (February 11, 2022) ##
22
-
23
- * No changes.
24
-
25
-
26
- ## Rails 6.1.4.4 (December 15, 2021) ##
27
-
28
- * No changes.
29
-
30
-
31
- ## Rails 6.1.4.3 (December 14, 2021) ##
32
-
33
- * No changes.
34
-
35
-
36
- ## Rails 6.1.4.2 (December 14, 2021) ##
37
-
38
- * No changes.
39
-
40
-
41
- ## Rails 6.1.4.1 (August 19, 2021) ##
42
-
43
- * No changes.
44
-
45
-
46
- ## Rails 6.1.4 (June 24, 2021) ##
47
-
48
- * No changes.
49
-
50
-
51
- ## Rails 6.1.3.2 (May 05, 2021) ##
52
-
53
- * No changes.
54
-
55
-
56
- ## Rails 6.1.3.1 (March 26, 2021) ##
57
-
58
- * No changes.
59
-
60
-
61
- ## Rails 6.1.3 (February 17, 2021) ##
62
-
63
- * No changes.
64
-
65
-
66
- ## Rails 6.1.2.1 (February 10, 2021) ##
67
-
68
- * No changes.
69
-
70
-
71
- ## Rails 6.1.2 (February 09, 2021) ##
72
-
73
- * No changes.
74
-
75
-
76
- ## Rails 6.1.1 (January 07, 2021) ##
77
-
78
- * Make `retry_job` return the job that was created.
79
-
80
- *Rafael Mendonça França*
81
-
82
- * Include `ActiveSupport::Testing::Assertions` in `ActiveJob::TestHelpers`.
83
-
84
- *Mikkel Malmberg*
85
-
86
-
87
- ## Rails 6.1.0 (December 09, 2020) ##
88
-
89
- * Recover nano precision when serializing `Time`, `TimeWithZone` and `DateTime` objects.
90
-
91
- *Alan Tan*
92
-
93
- * Deprecate `config.active_job.return_false_on_aborted_enqueue`.
94
-
95
- *Rafael Mendonça França*
96
-
97
- * Return `false` when enqueuing a job is aborted.
98
-
99
- *Rafael Mendonça França*
100
-
101
- * While using `perform_enqueued_jobs` test helper enqueued jobs must be stored for the later check with
102
- `assert_enqueued_with`.
103
-
104
- *Dmitry Polushkin*
105
-
106
- * `ActiveJob::TestCase#perform_enqueued_jobs` without a block removes performed jobs from the queue.
107
-
108
- That way the helper can be called multiple times and not perform a job invocation multiple times.
109
-
110
- ```ruby
111
- def test_jobs
112
- HelloJob.perform_later("rafael")
113
- perform_enqueued_jobs # only runs with "rafael"
114
- HelloJob.perform_later("david")
115
- perform_enqueued_jobs # only runs with "david"
116
- end
117
- ```
118
-
119
- *Étienne Barrié*
120
-
121
- * `ActiveJob::TestCase#perform_enqueued_jobs` will no longer perform retries:
122
-
123
- When calling `perform_enqueued_jobs` without a block, the adapter will
124
- now perform jobs that are **already** in the queue. Jobs that will end up in
125
- the queue afterwards won't be performed.
126
-
127
- This change only affects `perform_enqueued_jobs` when no block is given.
128
-
129
- *Edouard Chin*
130
-
131
- * Add queue name support to Que adapter.
132
-
133
- *Brad Nauta*, *Wojciech Wnętrzak*
134
-
135
- * Don't run `after_enqueue` and `after_perform` callbacks if the callback chain is halted.
136
-
137
- class MyJob < ApplicationJob
138
- before_enqueue { throw(:abort) }
139
- after_enqueue { # won't enter here anymore }
13
+ # the actual job code
140
14
  end
141
15
 
142
- `after_enqueue` and `after_perform` callbacks will no longer run if the callback chain is halted.
143
- This behaviour is a breaking change and won't take effect until Rails 7.0.
144
- To enable this behaviour in your app right now, you can add in your app's configuration file
145
- `config.active_job.skip_after_callbacks_if_terminated = true`.
146
-
147
- *Edouard Chin*
16
+ *Daniel Morton*
148
17
 
149
- * Fix enqueuing and performing incorrect logging message.
18
+ * Added possibility to check on `:priority` in test helper methods
19
+ `assert_enqueued_with` and `assert_performed_with`.
150
20
 
151
- Jobs will no longer always log "Enqueued MyJob" or "Performed MyJob" when they actually didn't get enqueued/performed.
21
+ *Wojciech Wnętrzak*
152
22
 
153
- ```ruby
154
- class MyJob < ApplicationJob
155
- before_enqueue { throw(:abort) }
156
- end
23
+ * OpenSSL constants are now used for Digest computations.
157
24
 
158
- MyJob.perform_later # Will no longer log "Enqueued MyJob" since job wasn't even enqueued through adapter.
159
- ```
25
+ *Dirkjan Bussink*
160
26
 
161
- A new message will be logged in case a job couldn't be enqueued, either because the callback chain was halted or
162
- because an exception happened during enqueuing. (i.e. Redis is down when you try to enqueue your job)
27
+ * Add a Serializer for the Range class.
163
28
 
164
- *Edouard Chin*
29
+ This should allow things like `MyJob.perform_later(range: 1..100)`.
165
30
 
166
- * Add an option to disable logging of the job arguments when enqueuing and executing the job.
31
+ * Communicate enqueue failures to callers of `perform_later`.
167
32
 
168
- class SensitiveJob < ApplicationJob
169
- self.log_arguments = false
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.
170
40
 
171
- 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
172
46
  end
173
47
  end
174
48
 
175
- When dealing with sensitive arguments as password and tokens it is now possible to configure the job
176
- to not put the sensitive argument in the logs.
177
-
178
- *Rafael Mendonça França*
179
-
180
- * Changes in `queue_name_prefix` of a job no longer affects all other jobs.
181
-
182
- Fixes #37084.
183
-
184
- *Lucas Mansur*
185
-
186
- * Allow `Class` and `Module` instances to be serialized.
187
-
188
- *Kevin Deisz*
189
-
190
- * Log potential matches in `assert_enqueued_with` and `assert_performed_with`.
191
-
192
- *Gareth du Plooy*
193
-
194
- * Add `at` argument to the `perform_enqueued_jobs` test helper.
195
-
196
- *John Crepezzi*, *Eileen Uchitelle*
197
-
198
- * `assert_enqueued_with` and `assert_performed_with` can now test jobs with relative delay.
199
-
200
- *Vlado Cingel*
49
+ *Daniel Morton*
201
50
 
202
- * Add jitter to `ActiveJob::Exceptions.retry_on`.
51
+ * Don't log rescuable exceptions defined with `rescue_from`.
203
52
 
204
- `ActiveJob::Exceptions.retry_on` now uses a random amount of jitter in order to
205
- prevent the [thundering herd effect](https://en.wikipedia.org/wiki/Thundering_herd_problem). Defaults to
206
- 15% (represented as 0.15) but overridable via the `:jitter` option when using `retry_on`.
207
- Jitter is applied when an `Integer`, `ActiveSupport::Duration` or `:exponentially_longer`, is passed to the `wait` argument in `retry_on`.
53
+ *Hu Hailin*
208
54
 
209
- ```ruby
210
- retry_on(MyError, wait: :exponentially_longer, jitter: 0.30)
211
- ```
55
+ * Allow `rescue_from` to rescue all exceptions.
212
56
 
213
- *Anthony Ross*
57
+ *Adrianna Chang*, *Étienne Barrié*
214
58
 
215
59
 
216
- 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 = 6
13
- PRE = nil
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]
@@ -4,22 +4,25 @@ require "active_support/tagged_logging"
4
4
  require "active_support/logger"
5
5
 
6
6
  module ActiveJob
7
- module Logging #:nodoc:
7
+ module Logging # :nodoc:
8
8
  extend ActiveSupport::Concern
9
9
 
10
10
  included do
11
11
  cattr_accessor :logger, default: ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT))
12
12
  class_attribute :log_arguments, instance_accessor: false, default: true
13
13
 
14
- around_enqueue { |_, block| tag_logger(&block) }
15
- around_perform { |job, block| tag_logger(job.class.name, job.job_id, &block) }
14
+ around_enqueue(prepend: true) { |_, block| tag_logger(&block) }
15
+ end
16
+
17
+ def perform_now
18
+ tag_logger(self.class.name, self.job_id) { super }
16
19
  end
17
20
 
18
21
  private
19
- def tag_logger(*tags)
22
+ def tag_logger(*tags, &block)
20
23
  if logger.respond_to?(:tagged)
21
24
  tags.unshift "ActiveJob" unless logger_tagged_by_active_job?
22
- logger.tagged(*tags) { yield }
25
+ logger.tagged(*tags, &block)
23
26
  else
24
27
  yield
25
28
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveJob
4
+ module QueryTags # :nodoc:
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ around_perform :expose_job_to_query_logs
9
+ end
10
+
11
+ private
12
+ def expose_job_to_query_logs(&block)
13
+ ActiveRecord::QueryLogs.set_context(job: self, &block)
14
+ end
15
+ end
16
+ end
@@ -5,7 +5,7 @@ require "active_support/core_ext/string/inflections"
5
5
  module ActiveJob
6
6
  # The <tt>ActiveJob::QueueAdapter</tt> module is used to load the
7
7
  # correct adapter. The default queue adapter is the +:async+ queue.
8
- module QueueAdapter #:nodoc:
8
+ module QueueAdapter # :nodoc:
9
9
  extend ActiveSupport::Concern
10
10
 
11
11
  included do
@@ -36,23 +36,23 @@ module ActiveJob
36
36
  @scheduler = Scheduler.new(**executor_options)
37
37
  end
38
38
 
39
- def enqueue(job) #:nodoc:
39
+ def enqueue(job) # :nodoc:
40
40
  @scheduler.enqueue JobWrapper.new(job), queue_name: job.queue_name
41
41
  end
42
42
 
43
- def enqueue_at(job, timestamp) #:nodoc:
43
+ def enqueue_at(job, timestamp) # :nodoc:
44
44
  @scheduler.enqueue_at JobWrapper.new(job), timestamp, queue_name: job.queue_name
45
45
  end
46
46
 
47
47
  # Gracefully stop processing jobs. Finishes in-progress work and handles
48
48
  # any new jobs following the executor's fallback policy (`caller_runs`).
49
49
  # Waits for termination by default. Pass `wait: false` to continue.
50
- def shutdown(wait: true) #:nodoc:
50
+ def shutdown(wait: true) # :nodoc:
51
51
  @scheduler.shutdown wait: wait
52
52
  end
53
53
 
54
54
  # Used for our test suite.
55
- def immediate=(immediate) #:nodoc:
55
+ def immediate=(immediate) # :nodoc:
56
56
  @scheduler.immediate = immediate
57
57
  end
58
58
 
@@ -60,7 +60,7 @@ module ActiveJob
60
60
  # performing them in-process, but we do so anyway for parity with other
61
61
  # adapters and deployment environments. Otherwise, serialization bugs
62
62
  # may creep in undetected.
63
- class JobWrapper #:nodoc:
63
+ class JobWrapper # :nodoc:
64
64
  def initialize(job)
65
65
  job.provider_job_id = SecureRandom.uuid
66
66
  @job_data = job.serialize
@@ -71,7 +71,7 @@ module ActiveJob
71
71
  end
72
72
  end
73
73
 
74
- class Scheduler #:nodoc:
74
+ class Scheduler # :nodoc:
75
75
  DEFAULT_EXECUTOR_OPTIONS = {
76
76
  min_threads: 0,
77
77
  max_threads: Concurrent.processor_count,
@@ -15,16 +15,16 @@ module ActiveJob
15
15
  #
16
16
  # Rails.application.config.active_job.queue_adapter = :backburner
17
17
  class BackburnerAdapter
18
- def enqueue(job) #:nodoc:
18
+ def enqueue(job) # :nodoc:
19
19
  Backburner::Worker.enqueue(JobWrapper, [job.serialize], queue: job.queue_name, pri: job.priority)
20
20
  end
21
21
 
22
- def enqueue_at(job, timestamp) #:nodoc:
22
+ def enqueue_at(job, timestamp) # :nodoc:
23
23
  delay = timestamp - Time.current.to_f
24
24
  Backburner::Worker.enqueue(JobWrapper, [job.serialize], queue: job.queue_name, pri: job.priority, delay: delay)
25
25
  end
26
26
 
27
- class JobWrapper #:nodoc:
27
+ class JobWrapper # :nodoc:
28
28
  class << self
29
29
  def perform(job_data)
30
30
  Base.execute job_data
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "delayed_job"
4
+ require "active_support/core_ext/string/inflections"
4
5
 
5
6
  module ActiveJob
6
7
  module QueueAdapters
@@ -15,19 +16,19 @@ module ActiveJob
15
16
  #
16
17
  # Rails.application.config.active_job.queue_adapter = :delayed_job
17
18
  class DelayedJobAdapter
18
- def enqueue(job) #:nodoc:
19
+ def enqueue(job) # :nodoc:
19
20
  delayed_job = Delayed::Job.enqueue(JobWrapper.new(job.serialize), queue: job.queue_name, priority: job.priority)
20
21
  job.provider_job_id = delayed_job.id
21
22
  delayed_job
22
23
  end
23
24
 
24
- def enqueue_at(job, timestamp) #:nodoc:
25
+ def enqueue_at(job, timestamp) # :nodoc:
25
26
  delayed_job = Delayed::Job.enqueue(JobWrapper.new(job.serialize), queue: job.queue_name, priority: job.priority, run_at: Time.at(timestamp))
26
27
  job.provider_job_id = delayed_job.id
27
28
  delayed_job
28
29
  end
29
30
 
30
- class JobWrapper #:nodoc:
31
+ class JobWrapper # :nodoc:
31
32
  attr_accessor :job_data
32
33
 
33
34
  def initialize(job_data)
@@ -35,12 +36,21 @@ module ActiveJob
35
36
  end
36
37
 
37
38
  def display_name
38
- "#{job_data['job_class']} [#{job_data['job_id']}] from DelayedJob(#{job_data['queue_name']}) with arguments: #{job_data['arguments']}"
39
+ base_name = "#{job_data["job_class"]} [#{job_data["job_id"]}] from DelayedJob(#{job_data["queue_name"]})"
40
+
41
+ return base_name unless log_arguments?
42
+
43
+ "#{base_name} with arguments: #{job_data["arguments"]}"
39
44
  end
40
45
 
41
46
  def perform
42
47
  Base.execute(job_data)
43
48
  end
49
+
50
+ private
51
+ def log_arguments?
52
+ job_data["job_class"].constantize.log_arguments?
53
+ end
44
54
  end
45
55
  end
46
56
  end
@@ -11,11 +11,11 @@ module ActiveJob
11
11
  #
12
12
  # Rails.application.config.active_job.queue_adapter = :inline
13
13
  class InlineAdapter
14
- def enqueue(job) #:nodoc:
14
+ def enqueue(job) # :nodoc:
15
15
  Base.execute(job.serialize)
16
16
  end
17
17
 
18
- def enqueue_at(*) #:nodoc:
18
+ def enqueue_at(*) # :nodoc:
19
19
  raise NotImplementedError, "Use a queueing backend to enqueue jobs in the future. Read more at https://guides.rubyonrails.org/active_job_basics.html"
20
20
  end
21
21
  end
@@ -17,19 +17,19 @@ module ActiveJob
17
17
  #
18
18
  # Rails.application.config.active_job.queue_adapter = :que
19
19
  class QueAdapter
20
- def enqueue(job) #:nodoc:
20
+ def enqueue(job) # :nodoc:
21
21
  que_job = JobWrapper.enqueue job.serialize, priority: job.priority, queue: job.queue_name
22
22
  job.provider_job_id = que_job.attrs["job_id"]
23
23
  que_job
24
24
  end
25
25
 
26
- def enqueue_at(job, timestamp) #:nodoc:
26
+ def enqueue_at(job, timestamp) # :nodoc:
27
27
  que_job = JobWrapper.enqueue job.serialize, priority: job.priority, queue: job.queue_name, run_at: Time.at(timestamp)
28
28
  job.provider_job_id = que_job.attrs["job_id"]
29
29
  que_job
30
30
  end
31
31
 
32
- class JobWrapper < Que::Job #:nodoc:
32
+ class JobWrapper < Que::Job # :nodoc:
33
33
  def run(job_data)
34
34
  Base.execute job_data
35
35
  end
@@ -19,13 +19,13 @@ module ActiveJob
19
19
  #
20
20
  # Rails.application.config.active_job.queue_adapter = :queue_classic
21
21
  class QueueClassicAdapter
22
- def enqueue(job) #:nodoc:
22
+ def enqueue(job) # :nodoc:
23
23
  qc_job = build_queue(job.queue_name).enqueue("#{JobWrapper.name}.perform", job.serialize)
24
24
  job.provider_job_id = qc_job["id"] if qc_job.is_a?(Hash)
25
25
  qc_job
26
26
  end
27
27
 
28
- def enqueue_at(job, timestamp) #:nodoc:
28
+ def enqueue_at(job, timestamp) # :nodoc:
29
29
  queue = build_queue(job.queue_name)
30
30
  unless queue.respond_to?(:enqueue_at)
31
31
  raise NotImplementedError, "To be able to schedule jobs with queue_classic " \
@@ -46,7 +46,7 @@ module ActiveJob
46
46
  QC::Queue.new(queue_name)
47
47
  end
48
48
 
49
- class JobWrapper #:nodoc:
49
+ class JobWrapper # :nodoc:
50
50
  class << self
51
51
  def perform(job_data)
52
52
  Base.execute job_data
@@ -28,12 +28,12 @@ module ActiveJob
28
28
  #
29
29
  # Rails.application.config.active_job.queue_adapter = :resque
30
30
  class ResqueAdapter
31
- def enqueue(job) #:nodoc:
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
34
34
  end
35
35
 
36
- def enqueue_at(job, timestamp) #:nodoc:
36
+ def enqueue_at(job, timestamp) # :nodoc:
37
37
  unless Resque.respond_to?(:enqueue_at_with_queue)
38
38
  raise NotImplementedError, "To be able to schedule jobs with Resque you need the " \
39
39
  "resque-scheduler gem. Please add it to your Gemfile and run bundle install"
@@ -41,7 +41,7 @@ module ActiveJob
41
41
  Resque.enqueue_at_with_queue job.queue_name, timestamp, JobWrapper, job.serialize
42
42
  end
43
43
 
44
- class JobWrapper #:nodoc:
44
+ class JobWrapper # :nodoc:
45
45
  class << self
46
46
  def perform(job_data)
47
47
  Base.execute job_data
@@ -17,7 +17,7 @@ module ActiveJob
17
17
  #
18
18
  # Rails.application.config.active_job.queue_adapter = :sidekiq
19
19
  class SidekiqAdapter
20
- def enqueue(job) #:nodoc:
20
+ def enqueue(job) # :nodoc:
21
21
  # Sidekiq::Client does not support symbols as keys
22
22
  job.provider_job_id = Sidekiq::Client.push \
23
23
  "class" => JobWrapper,
@@ -26,7 +26,7 @@ module ActiveJob
26
26
  "args" => [ job.serialize ]
27
27
  end
28
28
 
29
- def enqueue_at(job, timestamp) #:nodoc:
29
+ def enqueue_at(job, timestamp) # :nodoc:
30
30
  job.provider_job_id = Sidekiq::Client.push \
31
31
  "class" => JobWrapper,
32
32
  "wrapped" => job.class,
@@ -35,7 +35,7 @@ module ActiveJob
35
35
  "at" => timestamp
36
36
  end
37
37
 
38
- class JobWrapper #:nodoc:
38
+ class JobWrapper # :nodoc:
39
39
  include Sidekiq::Worker
40
40
 
41
41
  def perform(job_data)
@@ -22,18 +22,18 @@ module ActiveJob
22
22
  @monitor = Monitor.new
23
23
  end
24
24
 
25
- def enqueue(job) #:nodoc:
25
+ def enqueue(job) # :nodoc:
26
26
  @monitor.synchronize do
27
27
  JobWrapper.from_queue job.queue_name
28
28
  JobWrapper.enqueue ActiveSupport::JSON.encode(job.serialize)
29
29
  end
30
30
  end
31
31
 
32
- def enqueue_at(job, timestamp) #:nodoc:
32
+ def enqueue_at(job, timestamp) # :nodoc:
33
33
  raise NotImplementedError, "This queueing backend does not support scheduling jobs. To see what features are supported go to http://api.rubyonrails.org/classes/ActiveJob/QueueAdapters.html"
34
34
  end
35
35
 
36
- class JobWrapper #:nodoc:
36
+ class JobWrapper # :nodoc:
37
37
  include Sneakers::Worker
38
38
  from_queue "default"
39
39
 
@@ -18,7 +18,7 @@ module ActiveJob
18
18
  #
19
19
  # Rails.application.config.active_job.queue_adapter = :sucker_punch
20
20
  class SuckerPunchAdapter
21
- def enqueue(job) #:nodoc:
21
+ def enqueue(job) # :nodoc:
22
22
  if JobWrapper.respond_to?(:perform_async)
23
23
  # sucker_punch 2.0 API
24
24
  JobWrapper.perform_async job.serialize
@@ -28,7 +28,7 @@ module ActiveJob
28
28
  end
29
29
  end
30
30
 
31
- def enqueue_at(job, timestamp) #:nodoc:
31
+ def enqueue_at(job, timestamp) # :nodoc:
32
32
  if JobWrapper.respond_to?(:perform_in)
33
33
  delay = timestamp - Time.current.to_f
34
34
  JobWrapper.perform_in delay, job.serialize
@@ -37,7 +37,7 @@ module ActiveJob
37
37
  end
38
38
  end
39
39
 
40
- class JobWrapper #:nodoc:
40
+ class JobWrapper # :nodoc:
41
41
  include SuckerPunch::Job
42
42
 
43
43
  def perform(job_data)
@@ -25,12 +25,12 @@ module ActiveJob
25
25
  @performed_jobs ||= []
26
26
  end
27
27
 
28
- def enqueue(job) #:nodoc:
28
+ def enqueue(job) # :nodoc:
29
29
  job_data = job_to_hash(job)
30
30
  perform_or_enqueue(perform_enqueued_jobs && !filtered?(job), job, job_data)
31
31
  end
32
32
 
33
- def enqueue_at(job, timestamp) #:nodoc:
33
+ def enqueue_at(job, timestamp) # :nodoc:
34
34
  job_data = job_to_hash(job, at: timestamp)
35
35
  perform_or_enqueue(perform_enqueued_at_jobs && !filtered?(job), job, job_data)
36
36
  end
@@ -41,6 +41,7 @@ module ActiveJob
41
41
  job_data[:job] = job.class
42
42
  job_data[:args] = job_data.fetch("arguments")
43
43
  job_data[:queue] = job_data.fetch("queue_name")
44
+ job_data[:priority] = job_data.fetch("priority")
44
45
  end.merge(extras)
45
46
  end
46
47
 
@@ -45,7 +45,7 @@ module ActiveJob
45
45
  end
46
46
  end
47
47
 
48
- def queue_name_from_part(part_name) #:nodoc:
48
+ def queue_name_from_part(part_name) # :nodoc:
49
49
  queue_name = part_name || default_queue_name
50
50
  name_parts = [queue_name_prefix.presence, queue_name]
51
51
  -name_parts.compact.join(queue_name_delimiter)
@@ -8,6 +8,7 @@ module ActiveJob
8
8
  class Railtie < Rails::Railtie # :nodoc:
9
9
  config.active_job = ActiveSupport::OrderedOptions.new
10
10
  config.active_job.custom_serializers = []
11
+ config.active_job.log_query_tags_around_perform = true
11
12
 
12
13
  initializer "active_job.logger" do
13
14
  ActiveSupport.on_load(:active_job) { self.logger = ::Rails.logger }
@@ -15,7 +16,7 @@ module ActiveJob
15
16
 
16
17
  initializer "active_job.custom_serializers" do |app|
17
18
  config.after_initialize do
18
- custom_serializers = app.config.active_job.delete(:custom_serializers)
19
+ custom_serializers = app.config.active_job.custom_serializers
19
20
  ActiveJob::Serializers.add_serializers custom_serializers
20
21
  end
21
22
  end
@@ -25,6 +26,12 @@ module ActiveJob
25
26
  options.queue_adapter ||= :async
26
27
 
27
28
  ActiveSupport.on_load(:active_job) do
29
+ # Configs used in other initializers
30
+ options = options.except(
31
+ :log_query_tags_around_perform,
32
+ :custom_serializers
33
+ )
34
+
28
35
  options.each do |k, v|
29
36
  k = "#{k}="
30
37
  send(k, v) if respond_to? k
@@ -49,5 +56,23 @@ module ActiveJob
49
56
  end
50
57
  end
51
58
  end
59
+
60
+ initializer "active_job.query_log_tags" do |app|
61
+ query_logs_tags_enabled = app.config.respond_to?(:active_record) &&
62
+ app.config.active_record.query_log_tags_enabled &&
63
+ app.config.active_job.log_query_tags_around_perform
64
+
65
+ if query_logs_tags_enabled
66
+ app.config.active_record.query_log_tags << :job
67
+
68
+ ActiveSupport.on_load(:active_job) do
69
+ include ActiveJob::QueryTags
70
+ end
71
+
72
+ ActiveSupport.on_load(:active_record) do
73
+ ActiveRecord::QueryLogs.taggings[:job] = ->(context) { context[:job].class.name unless context[:job].nil? }
74
+ end
75
+ end
76
+ end
52
77
  end
53
78
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveJob
4
+ module Serializers
5
+ class RangeSerializer < ObjectSerializer
6
+ KEYS = %w[begin end exclude_end].freeze
7
+
8
+ def serialize(range)
9
+ args = Arguments.serialize([range.begin, range.end, range.exclude_end?])
10
+ super(KEYS.zip(args).to_h)
11
+ end
12
+
13
+ def deserialize(hash)
14
+ klass.new(*Arguments.deserialize(hash.values_at(*KEYS)))
15
+ end
16
+
17
+ private
18
+ def klass
19
+ ::Range
20
+ end
21
+ end
22
+ end
23
+ end
@@ -17,6 +17,7 @@ module ActiveJob
17
17
  autoload :TimeWithZoneSerializer
18
18
  autoload :TimeSerializer
19
19
  autoload :ModuleSerializer
20
+ autoload :RangeSerializer
20
21
 
21
22
  mattr_accessor :_additional_serializers
22
23
  self._additional_serializers = Set.new
@@ -61,6 +62,7 @@ module ActiveJob
61
62
  DateSerializer,
62
63
  TimeWithZoneSerializer,
63
64
  TimeSerializer,
64
- ModuleSerializer
65
+ ModuleSerializer,
66
+ RangeSerializer
65
67
  end
66
68
  end
@@ -124,7 +124,7 @@ module ActiveJob
124
124
  if block_given?
125
125
  original_jobs = enqueued_jobs_with(only: only, except: except, queue: queue)
126
126
 
127
- assert_nothing_raised(&block)
127
+ _assert_nothing_raised_or_warn("assert_enqueued_jobs", &block)
128
128
 
129
129
  new_jobs = enqueued_jobs_with(only: only, except: except, queue: queue)
130
130
 
@@ -389,15 +389,15 @@ module ActiveJob
389
389
  # MyJob.set(wait_until: Date.tomorrow.noon).perform_later
390
390
  # end
391
391
  # end
392
- def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil, &block)
393
- expected = { job: job, args: args, at: at, queue: queue }.compact
392
+ def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil, priority: nil, &block)
393
+ expected = { job: job, args: args, at: at, queue: queue, priority: priority }.compact
394
394
  expected_args = prepare_args_for_assertion(expected)
395
395
  potential_matches = []
396
396
 
397
397
  if block_given?
398
398
  original_enqueued_jobs = enqueued_jobs.dup
399
399
 
400
- assert_nothing_raised(&block)
400
+ _assert_nothing_raised_or_warn("assert_enqueued_with", &block)
401
401
 
402
402
  jobs = enqueued_jobs - original_enqueued_jobs
403
403
  else
@@ -479,8 +479,8 @@ module ActiveJob
479
479
  # MyJob.set(wait_until: Date.tomorrow.noon).perform_later
480
480
  # end
481
481
  # end
482
- def assert_performed_with(job: nil, args: nil, at: nil, queue: nil, &block)
483
- expected = { job: job, args: args, at: at, queue: queue }.compact
482
+ def assert_performed_with(job: nil, args: nil, at: nil, queue: nil, priority: nil, &block)
483
+ expected = { job: job, args: args, at: at, queue: queue, priority: priority }.compact
484
484
  expected_args = prepare_args_for_assertion(expected)
485
485
  potential_matches = []
486
486
 
@@ -591,7 +591,7 @@ module ActiveJob
591
591
  queue_adapter.queue = queue
592
592
  queue_adapter.at = at
593
593
 
594
- assert_nothing_raised(&block)
594
+ _assert_nothing_raised_or_warn("perform_enqueued_jobs", &block)
595
595
  ensure
596
596
  queue_adapter.perform_enqueued_jobs = old_perform_enqueued_jobs
597
597
  queue_adapter.perform_enqueued_at_jobs = old_perform_enqueued_at_jobs
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveJob
4
- module Timezones #:nodoc:
4
+ module Timezones # :nodoc:
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveJob
4
- module Translation #:nodoc:
4
+ module Translation # :nodoc:
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
data/lib/active_job.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  #--
4
- # Copyright (c) 2014-2022 David Heinemeier Hansson
4
+ # Copyright (c) 2014-2021 David Heinemeier Hansson
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
7
7
  # a copy of this software and associated documentation files (the
@@ -37,4 +37,5 @@ module ActiveJob
37
37
  autoload :ConfiguredJob
38
38
  autoload :TestCase
39
39
  autoload :TestHelper
40
+ autoload :QueryTags
40
41
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activejob
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.1.6
4
+ version: 7.0.0.alpha1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-09 00:00:00.000000000 Z
11
+ date: 2021-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 6.1.6
19
+ version: 7.0.0.alpha1
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: 6.1.6
26
+ version: 7.0.0.alpha1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: globalid
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -60,6 +60,7 @@ files:
60
60
  - lib/active_job/instrumentation.rb
61
61
  - lib/active_job/log_subscriber.rb
62
62
  - lib/active_job/logging.rb
63
+ - lib/active_job/query_tags.rb
63
64
  - lib/active_job/queue_adapter.rb
64
65
  - lib/active_job/queue_adapters.rb
65
66
  - lib/active_job/queue_adapters/async_adapter.rb
@@ -82,6 +83,7 @@ files:
82
83
  - lib/active_job/serializers/duration_serializer.rb
83
84
  - lib/active_job/serializers/module_serializer.rb
84
85
  - lib/active_job/serializers/object_serializer.rb
86
+ - lib/active_job/serializers/range_serializer.rb
85
87
  - lib/active_job/serializers/symbol_serializer.rb
86
88
  - lib/active_job/serializers/time_object_serializer.rb
87
89
  - lib/active_job/serializers/time_serializer.rb
@@ -99,12 +101,11 @@ licenses:
99
101
  - MIT
100
102
  metadata:
101
103
  bug_tracker_uri: https://github.com/rails/rails/issues
102
- changelog_uri: https://github.com/rails/rails/blob/v6.1.6/activejob/CHANGELOG.md
103
- documentation_uri: https://api.rubyonrails.org/v6.1.6/
104
+ changelog_uri: https://github.com/rails/rails/blob/v7.0.0.alpha1/activejob/CHANGELOG.md
105
+ documentation_uri: https://api.rubyonrails.org/v7.0.0.alpha1/
104
106
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
105
- source_code_uri: https://github.com/rails/rails/tree/v6.1.6/activejob
106
- rubygems_mfa_required: 'true'
107
- post_install_message:
107
+ source_code_uri: https://github.com/rails/rails/tree/v7.0.0.alpha1/activejob
108
+ post_install_message:
108
109
  rdoc_options: []
109
110
  require_paths:
110
111
  - lib
@@ -112,15 +113,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
112
113
  requirements:
113
114
  - - ">="
114
115
  - !ruby/object:Gem::Version
115
- version: 2.5.0
116
+ version: 2.7.0
116
117
  required_rubygems_version: !ruby/object:Gem::Requirement
117
118
  requirements:
118
- - - ">="
119
+ - - ">"
119
120
  - !ruby/object:Gem::Version
120
- version: '0'
121
+ version: 1.3.1
121
122
  requirements: []
122
- rubygems_version: 3.3.7
123
- signing_key:
123
+ rubygems_version: 3.1.6
124
+ signing_key:
124
125
  specification_version: 4
125
126
  summary: Job framework with pluggable queues.
126
127
  test_files: []