activejob 6.1.3.1 → 7.0.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +36 -137
  3. data/MIT-LICENSE +1 -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/callbacks.rb +1 -1
  8. data/lib/active_job/configured_job.rb +5 -7
  9. data/lib/active_job/core.rb +11 -1
  10. data/lib/active_job/enqueuing.rb +22 -9
  11. data/lib/active_job/exceptions.rb +4 -2
  12. data/lib/active_job/execution.rb +12 -8
  13. data/lib/active_job/gem_version.rb +4 -4
  14. data/lib/active_job/instrumentation.rb +9 -5
  15. data/lib/active_job/log_subscriber.rb +1 -1
  16. data/lib/active_job/logging.rb +8 -5
  17. data/lib/active_job/query_tags.rb +16 -0
  18. data/lib/active_job/queue_adapter.rb +1 -1
  19. data/lib/active_job/queue_adapters/async_adapter.rb +6 -6
  20. data/lib/active_job/queue_adapters/backburner_adapter.rb +3 -3
  21. data/lib/active_job/queue_adapters/delayed_job_adapter.rb +14 -4
  22. data/lib/active_job/queue_adapters/inline_adapter.rb +2 -2
  23. data/lib/active_job/queue_adapters/que_adapter.rb +3 -3
  24. data/lib/active_job/queue_adapters/queue_classic_adapter.rb +3 -3
  25. data/lib/active_job/queue_adapters/resque_adapter.rb +3 -3
  26. data/lib/active_job/queue_adapters/sidekiq_adapter.rb +3 -3
  27. data/lib/active_job/queue_adapters/sneakers_adapter.rb +3 -3
  28. data/lib/active_job/queue_adapters/sucker_punch_adapter.rb +3 -3
  29. data/lib/active_job/queue_adapters/test_adapter.rb +3 -2
  30. data/lib/active_job/queue_name.rb +1 -1
  31. data/lib/active_job/railtie.rb +26 -1
  32. data/lib/active_job/serializers/range_serializer.rb +23 -0
  33. data/lib/active_job/serializers.rb +3 -1
  34. data/lib/active_job/test_helper.rb +7 -7
  35. data/lib/active_job/timezones.rb +1 -1
  36. data/lib/active_job/translation.rb +1 -1
  37. data/lib/active_job.rb +2 -1
  38. metadata +13 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6ad35f2f17e3e415f9a0ab6d5a30969886b46987e8d0d9109af802c55a2f79d
4
- data.tar.gz: 54fa1c9aaa61623e5372db847171d8e80753e6c75c4d878d30cc13c76364119a
3
+ metadata.gz: 34ec9d3dc4bb88ce5c06f50a5efb7d34fb383b38088a400a1dc307329be429a9
4
+ data.tar.gz: 8d2a9541a56b633fabb47adbf164d6568f7487ab07f5749e96917320c5f66b0a
5
5
  SHA512:
6
- metadata.gz: b5658e92e6b9608e4f0d313363ed9143bf31177f5e9ced083c82603c329d2b08fa9ca428b88e3b7a908c137e06fbfe6f8ea2b0dbd62446bfe52a328a6914cb65
7
- data.tar.gz: a6b928c2f7bb5b161dd54a0e7f73d0f99b5bb70ad904e1d4feb177cf89a18db1783fcbaaa94f66566afe54bb90a51e722aa77ac825282352c8bf2cb033fe395d
6
+ metadata.gz: 52b3116d2eba23f548e2af97a90a31fb544a0bb8c53e2642b6d0d8cdc03d419dc2de8bac6243b409b32d15fbf1af4da42e356f19df765d6b708b5b55b7283bb9
7
+ data.tar.gz: b8f3195cf56348deed886b834fe67a9f036b931f7b93c386888411d6aabc84467d87fc0a56ac2263b9d21df0e8294a3438d80e0748099ec1bd28bfcd4940c96e
data/CHANGELOG.md CHANGED
@@ -1,161 +1,60 @@
1
- ## Rails 6.1.3.1 (March 26, 2021) ##
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.3 (February 17, 2021) ##
10
+ class MyJob < ActiveJob::Base
11
+ retry_on(AlwaysRetryException, attempts: :unlimited)
7
12
 
8
- * No changes.
9
-
10
-
11
- ## Rails 6.1.2.1 (February 10, 2021) ##
12
-
13
- * No changes.
14
-
15
-
16
- ## Rails 6.1.2 (February 09, 2021) ##
17
-
18
- * No changes.
19
-
20
-
21
- ## Rails 6.1.1 (January 07, 2021) ##
22
-
23
- * Make `retry_job` return the job that was created.
24
-
25
- *Rafael Mendonça França*
26
-
27
- * Include `ActiveSupport::Testing::Assertions` in `ActiveJob::TestHelpers`.
28
-
29
- *Mikkel Malmberg*
30
-
31
-
32
- ## Rails 6.1.0 (December 09, 2020) ##
33
-
34
- * Recover nano precision when serializing `Time`, `TimeWithZone` and `DateTime` objects.
35
-
36
- *Alan Tan*
37
-
38
- * Deprecate `config.active_job.return_false_on_aborted_enqueue`.
39
-
40
- *Rafael Mendonça França*
41
-
42
- * Return `false` when enqueuing a job is aborted.
43
-
44
- *Rafael Mendonça França*
45
-
46
- * While using `perform_enqueued_jobs` test helper enqueued jobs must be stored for the later check with
47
- `assert_enqueued_with`.
48
-
49
- *Dmitry Polushkin*
50
-
51
- * `ActiveJob::TestCase#perform_enqueued_jobs` without a block removes performed jobs from the queue.
52
-
53
- That way the helper can be called multiple times and not perform a job invocation multiple times.
54
-
55
- ```ruby
56
- def test_jobs
57
- HelloJob.perform_later("rafael")
58
- perform_enqueued_jobs # only runs with "rafael"
59
- HelloJob.perform_later("david")
60
- perform_enqueued_jobs # only runs with "david"
61
- end
62
- ```
63
-
64
- *Étienne Barrié*
65
-
66
- * `ActiveJob::TestCase#perform_enqueued_jobs` will no longer perform retries:
67
-
68
- When calling `perform_enqueued_jobs` without a block, the adapter will
69
- now perform jobs that are **already** in the queue. Jobs that will end up in
70
- the queue afterwards won't be performed.
71
-
72
- This change only affects `perform_enqueued_jobs` when no block is given.
73
-
74
- *Edouard Chin*
75
-
76
- * Add queue name support to Que adapter.
77
-
78
- *Brad Nauta*, *Wojciech Wnętrzak*
79
-
80
- * Don't run `after_enqueue` and `after_perform` callbacks if the callback chain is halted.
81
-
82
- class MyJob < ApplicationJob
83
- before_enqueue { throw(:abort) }
84
- after_enqueue { # won't enter here anymore }
13
+ # the actual job code
85
14
  end
86
15
 
87
- `after_enqueue` and `after_perform` callbacks will no longer run if the callback chain is halted.
88
- This behaviour is a breaking change and won't take effect until Rails 6.2.
89
- To enable this behaviour in your app right now, you can add in your app's configuration file
90
- `config.active_job.skip_after_callbacks_if_terminated = true`.
91
-
92
- *Edouard Chin*
16
+ *Daniel Morton*
93
17
 
94
- * 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`.
95
20
 
96
- Jobs will no longer always log "Enqueued MyJob" or "Performed MyJob" when they actually didn't get enqueued/performed.
21
+ *Wojciech Wnętrzak*
97
22
 
98
- ```ruby
99
- class MyJob < ApplicationJob
100
- before_enqueue { throw(:abort) }
101
- end
23
+ * OpenSSL constants are now used for Digest computations.
102
24
 
103
- MyJob.perform_later # Will no longer log "Enqueued MyJob" since job wasn't even enqueued through adapter.
104
- ```
25
+ *Dirkjan Bussink*
105
26
 
106
- A new message will be logged in case a job couldn't be enqueued, either because the callback chain was halted or
107
- 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.
108
28
 
109
- *Edouard Chin*
29
+ This should allow things like `MyJob.perform_later(range: 1..100)`.
110
30
 
111
- * 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`.
112
32
 
113
- class SensitiveJob < ApplicationJob
114
- 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.
115
40
 
116
- 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
117
46
  end
118
47
  end
119
48
 
120
- When dealing with sensitive arguments as password and tokens it is now possible to configure the job
121
- to not put the sensitive argument in the logs.
122
-
123
- *Rafael Mendonça França*
124
-
125
- * Changes in `queue_name_prefix` of a job no longer affects all other jobs.
126
-
127
- Fixes #37084.
128
-
129
- *Lucas Mansur*
130
-
131
- * Allow `Class` and `Module` instances to be serialized.
132
-
133
- *Kevin Deisz*
134
-
135
- * Log potential matches in `assert_enqueued_with` and `assert_performed_with`.
136
-
137
- *Gareth du Plooy*
138
-
139
- * Add `at` argument to the `perform_enqueued_jobs` test helper.
140
-
141
- *John Crepezzi*, *Eileen Uchitelle*
142
-
143
- * `assert_enqueued_with` and `assert_performed_with` can now test jobs with relative delay.
144
-
145
- *Vlado Cingel*
49
+ *Daniel Morton*
146
50
 
147
- * Add jitter to `ActiveJob::Exceptions.retry_on`.
51
+ * Don't log rescuable exceptions defined with `rescue_from`.
148
52
 
149
- `ActiveJob::Exceptions.retry_on` now uses a random amount of jitter in order to
150
- prevent the [thundering herd effect](https://en.wikipedia.org/wiki/Thundering_herd_problem). Defaults to
151
- 15% (represented as 0.15) but overridable via the `:jitter` option when using `retry_on`.
152
- Jitter is applied when an `Integer`, `ActiveSupport::Duration` or `:exponentially_longer`, is passed to the `wait` argument in `retry_on`.
53
+ *Hu Hailin*
153
54
 
154
- ```ruby
155
- retry_on(MyError, wait: :exponentially_longer, jitter: 0.30)
156
- ```
55
+ * Allow `rescue_from` to rescue all exceptions.
157
56
 
158
- *Anthony Ross*
57
+ *Adrianna Chang*, *Étienne Barrié*
159
58
 
160
59
 
161
- 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-2020 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
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
 
@@ -186,7 +186,7 @@ module ActiveJob
186
186
 
187
187
  if !self.class.skip_after_callbacks_if_terminated && callbacks.any? { |c| c.kind == :after }
188
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`.
189
+ In Rails 7.0, `after_enqueue`/`after_perform` callbacks no longer run if `before_enqueue`/`before_perform` respectively halts with `throw :abort`.
190
190
  To enable this behavior, uncomment the `config.active_job.skip_after_callbacks_if_terminated` config
191
191
  in the new 6.1 framework defaults initializer.
192
192
  EOM
@@ -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 = 3
13
- PRE = "1"
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-2020 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.3.1
4
+ version: 7.0.0.alpha1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-26 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.3.1
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.3.1
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,10 +101,10 @@ 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.3.1/activejob/CHANGELOG.md
103
- documentation_uri: https://api.rubyonrails.org/v6.1.3.1/
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.3.1/activejob
107
+ source_code_uri: https://github.com/rails/rails/tree/v7.0.0.alpha1/activejob
106
108
  post_install_message:
107
109
  rdoc_options: []
108
110
  require_paths:
@@ -111,14 +113,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
113
  requirements:
112
114
  - - ">="
113
115
  - !ruby/object:Gem::Version
114
- version: 2.5.0
116
+ version: 2.7.0
115
117
  required_rubygems_version: !ruby/object:Gem::Requirement
116
118
  requirements:
117
- - - ">="
119
+ - - ">"
118
120
  - !ruby/object:Gem::Version
119
- version: '0'
121
+ version: 1.3.1
120
122
  requirements: []
121
- rubygems_version: 3.1.2
123
+ rubygems_version: 3.1.6
122
124
  signing_key:
123
125
  specification_version: 4
124
126
  summary: Job framework with pluggable queues.