activejob 6.1.6.1 → 7.0.0.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +36 -197
- data/MIT-LICENSE +2 -1
- data/README.md +3 -3
- data/lib/active_job/arguments.rb +10 -15
- data/lib/active_job/base.rb +2 -2
- data/lib/active_job/configured_job.rb +5 -7
- data/lib/active_job/core.rb +11 -1
- data/lib/active_job/enqueuing.rb +22 -9
- data/lib/active_job/exceptions.rb +4 -2
- data/lib/active_job/execution.rb +12 -8
- data/lib/active_job/gem_version.rb +4 -4
- data/lib/active_job/instrumentation.rb +9 -5
- data/lib/active_job/log_subscriber.rb +1 -1
- data/lib/active_job/logging.rb +8 -5
- data/lib/active_job/query_tags.rb +16 -0
- data/lib/active_job/queue_adapter.rb +1 -1
- data/lib/active_job/queue_adapters/async_adapter.rb +6 -6
- data/lib/active_job/queue_adapters/backburner_adapter.rb +3 -3
- data/lib/active_job/queue_adapters/delayed_job_adapter.rb +14 -4
- data/lib/active_job/queue_adapters/inline_adapter.rb +2 -2
- data/lib/active_job/queue_adapters/que_adapter.rb +3 -3
- data/lib/active_job/queue_adapters/queue_classic_adapter.rb +3 -3
- data/lib/active_job/queue_adapters/resque_adapter.rb +3 -3
- data/lib/active_job/queue_adapters/sidekiq_adapter.rb +3 -3
- data/lib/active_job/queue_adapters/sneakers_adapter.rb +3 -3
- data/lib/active_job/queue_adapters/sucker_punch_adapter.rb +3 -3
- data/lib/active_job/queue_adapters/test_adapter.rb +3 -2
- data/lib/active_job/queue_name.rb +1 -1
- data/lib/active_job/railtie.rb +26 -1
- data/lib/active_job/serializers/range_serializer.rb +23 -0
- data/lib/active_job/serializers.rb +3 -1
- data/lib/active_job/test_helper.rb +7 -7
- data/lib/active_job/timezones.rb +1 -1
- data/lib/active_job/translation.rb +1 -1
- data/lib/active_job.rb +2 -1
- metadata +16 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34ec9d3dc4bb88ce5c06f50a5efb7d34fb383b38088a400a1dc307329be429a9
|
4
|
+
data.tar.gz: 8d2a9541a56b633fabb47adbf164d6568f7487ab07f5749e96917320c5f66b0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52b3116d2eba23f548e2af97a90a31fb544a0bb8c53e2642b6d0d8cdc03d419dc2de8bac6243b409b32d15fbf1af4da42e356f19df765d6b708b5b55b7283bb9
|
7
|
+
data.tar.gz: b8f3195cf56348deed886b834fe67a9f036b931f7b93c386888411d6aabc84467d87fc0a56ac2263b9d21df0e8294a3438d80e0748099ec1bd28bfcd4940c96e
|
data/CHANGELOG.md
CHANGED
@@ -1,221 +1,60 @@
|
|
1
|
-
## Rails
|
1
|
+
## Rails 7.0.0.alpha1 (September 15, 2021) ##
|
2
2
|
|
3
|
-
*
|
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
|
-
|
10
|
+
class MyJob < ActiveJob::Base
|
11
|
+
retry_on(AlwaysRetryException, attempts: :unlimited)
|
7
12
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
## Rails 6.1.5 (March 09, 2022) ##
|
12
|
-
|
13
|
-
* No changes.
|
14
|
-
|
15
|
-
|
16
|
-
## Rails 6.1.4.7 (March 08, 2022) ##
|
17
|
-
|
18
|
-
* No changes.
|
19
|
-
|
20
|
-
|
21
|
-
## Rails 6.1.4.6 (February 11, 2022) ##
|
22
|
-
|
23
|
-
* No changes.
|
24
|
-
|
25
|
-
|
26
|
-
## Rails 6.1.4.5 (February 11, 2022) ##
|
27
|
-
|
28
|
-
* No changes.
|
29
|
-
|
30
|
-
|
31
|
-
## Rails 6.1.4.4 (December 15, 2021) ##
|
32
|
-
|
33
|
-
* No changes.
|
34
|
-
|
35
|
-
|
36
|
-
## Rails 6.1.4.3 (December 14, 2021) ##
|
37
|
-
|
38
|
-
* No changes.
|
39
|
-
|
40
|
-
|
41
|
-
## Rails 6.1.4.2 (December 14, 2021) ##
|
42
|
-
|
43
|
-
* No changes.
|
44
|
-
|
45
|
-
|
46
|
-
## Rails 6.1.4.1 (August 19, 2021) ##
|
47
|
-
|
48
|
-
* No changes.
|
49
|
-
|
50
|
-
|
51
|
-
## Rails 6.1.4 (June 24, 2021) ##
|
52
|
-
|
53
|
-
* No changes.
|
54
|
-
|
55
|
-
|
56
|
-
## Rails 6.1.3.2 (May 05, 2021) ##
|
57
|
-
|
58
|
-
* No changes.
|
59
|
-
|
60
|
-
|
61
|
-
## Rails 6.1.3.1 (March 26, 2021) ##
|
62
|
-
|
63
|
-
* No changes.
|
64
|
-
|
65
|
-
|
66
|
-
## Rails 6.1.3 (February 17, 2021) ##
|
67
|
-
|
68
|
-
* No changes.
|
69
|
-
|
70
|
-
|
71
|
-
## Rails 6.1.2.1 (February 10, 2021) ##
|
72
|
-
|
73
|
-
* No changes.
|
74
|
-
|
75
|
-
|
76
|
-
## Rails 6.1.2 (February 09, 2021) ##
|
77
|
-
|
78
|
-
* No changes.
|
79
|
-
|
80
|
-
|
81
|
-
## Rails 6.1.1 (January 07, 2021) ##
|
82
|
-
|
83
|
-
* Make `retry_job` return the job that was created.
|
84
|
-
|
85
|
-
*Rafael Mendonça França*
|
86
|
-
|
87
|
-
* Include `ActiveSupport::Testing::Assertions` in `ActiveJob::TestHelpers`.
|
88
|
-
|
89
|
-
*Mikkel Malmberg*
|
90
|
-
|
91
|
-
|
92
|
-
## Rails 6.1.0 (December 09, 2020) ##
|
93
|
-
|
94
|
-
* Recover nano precision when serializing `Time`, `TimeWithZone` and `DateTime` objects.
|
95
|
-
|
96
|
-
*Alan Tan*
|
97
|
-
|
98
|
-
* Deprecate `config.active_job.return_false_on_aborted_enqueue`.
|
99
|
-
|
100
|
-
*Rafael Mendonça França*
|
101
|
-
|
102
|
-
* Return `false` when enqueuing a job is aborted.
|
103
|
-
|
104
|
-
*Rafael Mendonça França*
|
105
|
-
|
106
|
-
* While using `perform_enqueued_jobs` test helper enqueued jobs must be stored for the later check with
|
107
|
-
`assert_enqueued_with`.
|
108
|
-
|
109
|
-
*Dmitry Polushkin*
|
110
|
-
|
111
|
-
* `ActiveJob::TestCase#perform_enqueued_jobs` without a block removes performed jobs from the queue.
|
112
|
-
|
113
|
-
That way the helper can be called multiple times and not perform a job invocation multiple times.
|
114
|
-
|
115
|
-
```ruby
|
116
|
-
def test_jobs
|
117
|
-
HelloJob.perform_later("rafael")
|
118
|
-
perform_enqueued_jobs # only runs with "rafael"
|
119
|
-
HelloJob.perform_later("david")
|
120
|
-
perform_enqueued_jobs # only runs with "david"
|
121
|
-
end
|
122
|
-
```
|
123
|
-
|
124
|
-
*Étienne Barrié*
|
125
|
-
|
126
|
-
* `ActiveJob::TestCase#perform_enqueued_jobs` will no longer perform retries:
|
127
|
-
|
128
|
-
When calling `perform_enqueued_jobs` without a block, the adapter will
|
129
|
-
now perform jobs that are **already** in the queue. Jobs that will end up in
|
130
|
-
the queue afterwards won't be performed.
|
131
|
-
|
132
|
-
This change only affects `perform_enqueued_jobs` when no block is given.
|
133
|
-
|
134
|
-
*Edouard Chin*
|
135
|
-
|
136
|
-
* Add queue name support to Que adapter.
|
137
|
-
|
138
|
-
*Brad Nauta*, *Wojciech Wnętrzak*
|
139
|
-
|
140
|
-
* Don't run `after_enqueue` and `after_perform` callbacks if the callback chain is halted.
|
141
|
-
|
142
|
-
class MyJob < ApplicationJob
|
143
|
-
before_enqueue { throw(:abort) }
|
144
|
-
after_enqueue { # won't enter here anymore }
|
13
|
+
# the actual job code
|
145
14
|
end
|
146
15
|
|
147
|
-
|
148
|
-
This behaviour is a breaking change and won't take effect until Rails 7.0.
|
149
|
-
To enable this behaviour in your app right now, you can add in your app's configuration file
|
150
|
-
`config.active_job.skip_after_callbacks_if_terminated = true`.
|
151
|
-
|
152
|
-
*Edouard Chin*
|
16
|
+
*Daniel Morton*
|
153
17
|
|
154
|
-
*
|
18
|
+
* Added possibility to check on `:priority` in test helper methods
|
19
|
+
`assert_enqueued_with` and `assert_performed_with`.
|
155
20
|
|
156
|
-
|
21
|
+
*Wojciech Wnętrzak*
|
157
22
|
|
158
|
-
|
159
|
-
class MyJob < ApplicationJob
|
160
|
-
before_enqueue { throw(:abort) }
|
161
|
-
end
|
23
|
+
* OpenSSL constants are now used for Digest computations.
|
162
24
|
|
163
|
-
|
164
|
-
```
|
25
|
+
*Dirkjan Bussink*
|
165
26
|
|
166
|
-
|
167
|
-
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.
|
168
28
|
|
169
|
-
|
29
|
+
This should allow things like `MyJob.perform_later(range: 1..100)`.
|
170
30
|
|
171
|
-
*
|
31
|
+
* Communicate enqueue failures to callers of `perform_later`.
|
172
32
|
|
173
|
-
|
174
|
-
|
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.
|
175
40
|
|
176
|
-
|
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
|
177
46
|
end
|
178
47
|
end
|
179
48
|
|
180
|
-
|
181
|
-
to not put the sensitive argument in the logs.
|
182
|
-
|
183
|
-
*Rafael Mendonça França*
|
184
|
-
|
185
|
-
* Changes in `queue_name_prefix` of a job no longer affects all other jobs.
|
186
|
-
|
187
|
-
Fixes #37084.
|
188
|
-
|
189
|
-
*Lucas Mansur*
|
190
|
-
|
191
|
-
* Allow `Class` and `Module` instances to be serialized.
|
192
|
-
|
193
|
-
*Kevin Deisz*
|
194
|
-
|
195
|
-
* Log potential matches in `assert_enqueued_with` and `assert_performed_with`.
|
196
|
-
|
197
|
-
*Gareth du Plooy*
|
198
|
-
|
199
|
-
* Add `at` argument to the `perform_enqueued_jobs` test helper.
|
200
|
-
|
201
|
-
*John Crepezzi*, *Eileen Uchitelle*
|
202
|
-
|
203
|
-
* `assert_enqueued_with` and `assert_performed_with` can now test jobs with relative delay.
|
204
|
-
|
205
|
-
*Vlado Cingel*
|
49
|
+
*Daniel Morton*
|
206
50
|
|
207
|
-
*
|
51
|
+
* Don't log rescuable exceptions defined with `rescue_from`.
|
208
52
|
|
209
|
-
|
210
|
-
prevent the [thundering herd effect](https://en.wikipedia.org/wiki/Thundering_herd_problem). Defaults to
|
211
|
-
15% (represented as 0.15) but overridable via the `:jitter` option when using `retry_on`.
|
212
|
-
Jitter is applied when an `Integer`, `ActiveSupport::Duration` or `:exponentially_longer`, is passed to the `wait` argument in `retry_on`.
|
53
|
+
*Hu Hailin*
|
213
54
|
|
214
|
-
|
215
|
-
retry_on(MyError, wait: :exponentially_longer, jitter: 0.30)
|
216
|
-
```
|
55
|
+
* Allow `rescue_from` to rescue all exceptions.
|
217
56
|
|
218
|
-
*
|
57
|
+
*Adrianna Chang*, *Étienne Barrié*
|
219
58
|
|
220
59
|
|
221
|
-
Please check [6-
|
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-
|
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
|
6
|
-
small units of work and run in parallel
|
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
|
-
|
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
|
data/lib/active_job/arguments.rb
CHANGED
@@ -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
|
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
|
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
|
-
|
77
|
-
|
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
|
91
|
-
args
|
92
|
-
|
93
|
-
|
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
|
}
|
data/lib/active_job/base.rb
CHANGED
@@ -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
|
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
|
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(
|
11
|
-
@job_class.new(
|
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(
|
16
|
-
@job_class.new(
|
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
|
data/lib/active_job/core.rb
CHANGED
@@ -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)
|
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.
|
data/lib/active_job/enqueuing.rb
CHANGED
@@ -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
|
-
|
22
|
-
|
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)
|
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?
|
data/lib/active_job/execution.rb
CHANGED
@@ -14,12 +14,11 @@ module ActiveJob
|
|
14
14
|
#
|
15
15
|
# MyJob.perform_now("mike")
|
16
16
|
#
|
17
|
-
def perform_now(
|
18
|
-
job_or_instantiate(
|
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)
|
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
|
-
|
48
|
-
|
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
|
@@ -1,21 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveJob
|
4
|
-
module Instrumentation
|
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
|
-
|
13
|
-
|
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
|
7
|
+
class LogSubscriber < ActiveSupport::LogSubscriber # :nodoc:
|
8
8
|
def enqueue(event)
|
9
9
|
job = event.payload[:job]
|
10
10
|
ex = event.payload[:exception_object]
|
data/lib/active_job/logging.rb
CHANGED
@@ -4,22 +4,25 @@ require "active_support/tagged_logging"
|
|
4
4
|
require "active_support/logger"
|
5
5
|
|
6
6
|
module ActiveJob
|
7
|
-
module Logging
|
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
|
-
|
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)
|
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
|
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)
|
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)
|
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)
|
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)
|
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
|
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
|
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)
|
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)
|
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
|
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)
|
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)
|
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
|
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[
|
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)
|
14
|
+
def enqueue(job) # :nodoc:
|
15
15
|
Base.execute(job.serialize)
|
16
16
|
end
|
17
17
|
|
18
|
-
def enqueue_at(*)
|
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)
|
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)
|
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
|
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)
|
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)
|
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
|
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)
|
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)
|
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
|
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)
|
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)
|
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
|
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)
|
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)
|
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
|
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)
|
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)
|
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
|
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)
|
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)
|
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)
|
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)
|
data/lib/active_job/railtie.rb
CHANGED
@@ -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.
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/active_job/timezones.rb
CHANGED
data/lib/active_job.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2014-
|
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:
|
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:
|
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:
|
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:
|
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/
|
103
|
-
documentation_uri: https://api.rubyonrails.org/
|
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/
|
106
|
-
|
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.
|
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:
|
121
|
+
version: 1.3.1
|
121
122
|
requirements: []
|
122
|
-
rubygems_version: 3.
|
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: []
|