activejob 7.0.8 → 7.2.0
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 +35 -214
- data/MIT-LICENSE +1 -1
- data/README.md +2 -2
- data/lib/active_job/arguments.rb +18 -32
- data/lib/active_job/base.rb +1 -1
- data/lib/active_job/callbacks.rb +3 -8
- data/lib/active_job/configured_job.rb +4 -0
- data/lib/active_job/core.rb +11 -6
- data/lib/active_job/deprecator.rb +7 -0
- data/lib/active_job/enqueue_after_transaction_commit.rb +28 -0
- data/lib/active_job/enqueuing.rb +71 -12
- data/lib/active_job/exceptions.rb +44 -7
- data/lib/active_job/execution.rb +5 -2
- data/lib/active_job/gem_version.rb +3 -3
- data/lib/active_job/instrumentation.rb +18 -10
- data/lib/active_job/log_subscriber.rb +80 -8
- data/lib/active_job/logging.rb +16 -2
- data/lib/active_job/queue_adapter.rb +18 -6
- data/lib/active_job/queue_adapters/abstract_adapter.rb +27 -0
- data/lib/active_job/queue_adapters/async_adapter.rb +3 -3
- data/lib/active_job/queue_adapters/backburner_adapter.rb +8 -4
- data/lib/active_job/queue_adapters/delayed_job_adapter.rb +10 -2
- data/lib/active_job/queue_adapters/inline_adapter.rb +6 -2
- data/lib/active_job/queue_adapters/queue_classic_adapter.rb +13 -5
- data/lib/active_job/queue_adapters/resque_adapter.rb +2 -2
- data/lib/active_job/queue_adapters/sidekiq_adapter.rb +43 -15
- data/lib/active_job/queue_adapters/sneakers_adapter.rb +2 -2
- data/lib/active_job/queue_adapters/sucker_punch_adapter.rb +4 -4
- data/lib/active_job/queue_adapters/test_adapter.rb +13 -5
- data/lib/active_job/queue_adapters.rb +9 -7
- data/lib/active_job/queue_priority.rb +18 -1
- data/lib/active_job/railtie.rb +38 -7
- data/lib/active_job/serializers/big_decimal_serializer.rb +22 -0
- data/lib/active_job/serializers/duration_serializer.rb +4 -2
- data/lib/active_job/serializers/object_serializer.rb +2 -0
- data/lib/active_job/serializers/time_with_zone_serializer.rb +11 -2
- data/lib/active_job/serializers.rb +7 -3
- data/lib/active_job/test_helper.rb +60 -19
- data/lib/active_job/version.rb +1 -1
- data/lib/active_job.rb +34 -4
- data/lib/rails/generators/job/USAGE +19 -0
- data/lib/rails/generators/job/job_generator.rb +6 -2
- data/lib/rails/generators/job/templates/job.rb.tt +1 -1
- metadata +14 -10
- data/lib/active_job/queue_adapters/que_adapter.rb +0 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 61775543f203855f8c8bdec31ddaa7d3c1413aab36a2de5665a726b7f5998307
|
4
|
+
data.tar.gz: 39b14d506be28b9c980fc69ac8910c8e31245aa8e19caa4a15b3511f9d90cac8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6351b9fb7e90d452428f30db98315ff523cbd781f409df3fba0ae7241fdedc0ae52514a3d5c4acd01b9474e235844e683a832f6631d65e8ea77b261bea0b3cf9
|
7
|
+
data.tar.gz: 9e18505077f83dd8924cb866138d0809b83fb9df68623f9a5e67cc0dbe1fcdcaea4a59c9de5cd9a4884684a1202b54a8ad0da657f08f5474a6790d20436be130
|
data/CHANGELOG.md
CHANGED
@@ -1,246 +1,67 @@
|
|
1
|
-
## Rails 7.0
|
1
|
+
## Rails 7.2.0 (August 09, 2024) ##
|
2
2
|
|
3
|
-
*
|
4
|
-
when the adapter raises an `ActiveJob::EnqueueError`.
|
3
|
+
* All tests now respect the `active_job.queue_adapter` config.
|
5
4
|
|
6
|
-
|
5
|
+
Previously if you had set `config.active_job.queue_adapter` in your `config/application.rb`
|
6
|
+
or `config/environments/test.rb` file, the adapter you selected was previously not used consistently
|
7
|
+
across all tests. In some tests your adapter would be used, but other tests would use the `TestAdapter`.
|
7
8
|
|
9
|
+
In Rails 7.2, all tests will respect the `queue_adapter` config if provided. If no config is provided,
|
10
|
+
the `TestAdapter` will continue to be used.
|
8
11
|
|
9
|
-
|
10
|
-
|
11
|
-
* No changes.
|
12
|
-
|
13
|
-
|
14
|
-
## Rails 7.0.7.1 (August 22, 2023) ##
|
15
|
-
|
16
|
-
* No changes.
|
17
|
-
|
18
|
-
|
19
|
-
## Rails 7.0.7 (August 09, 2023) ##
|
20
|
-
|
21
|
-
* No changes.
|
22
|
-
|
23
|
-
|
24
|
-
## Rails 7.0.6 (June 29, 2023) ##
|
25
|
-
|
26
|
-
* Fix error Active Job passed class with `permitted?`.
|
27
|
-
|
28
|
-
*Alex Baldwin*
|
29
|
-
|
30
|
-
|
31
|
-
## Rails 7.0.5.1 (June 26, 2023) ##
|
32
|
-
|
33
|
-
* No changes.
|
34
|
-
|
35
|
-
|
36
|
-
## Rails 7.0.5 (May 24, 2023) ##
|
37
|
-
|
38
|
-
* Make delayed job `display_name` failsafe.
|
39
|
-
|
40
|
-
*codez*
|
41
|
-
|
42
|
-
* Don't double log the `job` when using `ActiveRecord::QueryLog`
|
43
|
-
|
44
|
-
Previously if you set `config.active_record.query_log_tags` to an array that included
|
45
|
-
`:job`, the job name would get logged twice. This bug has been fixed.
|
12
|
+
See [#48585](https://github.com/rails/rails/pull/48585) for more details.
|
46
13
|
|
47
14
|
*Alex Ghiculescu*
|
48
15
|
|
16
|
+
* Make Active Job transaction aware when used conjointly with Active Record.
|
49
17
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
## Rails 7.0.4.2 (January 24, 2023) ##
|
56
|
-
|
57
|
-
* No changes.
|
58
|
-
|
59
|
-
|
60
|
-
## Rails 7.0.4.1 (January 17, 2023) ##
|
61
|
-
|
62
|
-
* No changes.
|
63
|
-
|
64
|
-
|
65
|
-
## Rails 7.0.4 (September 09, 2022) ##
|
66
|
-
|
67
|
-
* Update `ActiveJob::QueueAdapters::QueAdapter` to remove deprecation warning.
|
68
|
-
|
69
|
-
Remove a deprecation warning introduced in que 1.2 to prepare for changes in
|
70
|
-
que 2.0 necessary for Ruby 3 compatibility.
|
71
|
-
|
72
|
-
*Damir Zekic* and *Adis Hasovic*
|
73
|
-
|
74
|
-
## Rails 7.0.3.1 (July 12, 2022) ##
|
75
|
-
|
76
|
-
* No changes.
|
77
|
-
|
78
|
-
|
79
|
-
## Rails 7.0.3 (May 09, 2022) ##
|
80
|
-
|
81
|
-
* Add missing `bigdecimal` require in `ActiveJob::Arguments`
|
82
|
-
|
83
|
-
Could cause `uninitialized constant ActiveJob::Arguments::BigDecimal (NameError)`
|
84
|
-
when loading Active Job in isolation.
|
85
|
-
|
86
|
-
*Jean Boussier*
|
87
|
-
|
88
|
-
## Rails 7.0.2.4 (April 26, 2022) ##
|
89
|
-
|
90
|
-
* No changes.
|
91
|
-
|
92
|
-
|
93
|
-
## Rails 7.0.2.3 (March 08, 2022) ##
|
94
|
-
|
95
|
-
* No changes.
|
96
|
-
|
97
|
-
|
98
|
-
## Rails 7.0.2.2 (February 11, 2022) ##
|
99
|
-
|
100
|
-
* No changes.
|
101
|
-
|
102
|
-
|
103
|
-
## Rails 7.0.2.1 (February 11, 2022) ##
|
104
|
-
|
105
|
-
* No changes.
|
106
|
-
|
107
|
-
|
108
|
-
## Rails 7.0.2 (February 08, 2022) ##
|
109
|
-
|
110
|
-
* No changes.
|
111
|
-
|
112
|
-
|
113
|
-
## Rails 7.0.1 (January 06, 2022) ##
|
114
|
-
|
115
|
-
* Allow testing `discard_on/retry_on ActiveJob::DeserializationError`
|
116
|
-
|
117
|
-
Previously in `perform_enqueued_jobs`, `deserialize_arguments_if_needed`
|
118
|
-
was called before calling `perform_now`. When a record no longer exists
|
119
|
-
and is serialized using GlobalID this led to raising
|
120
|
-
an `ActiveJob::DeserializationError` before reaching `perform_now` call.
|
121
|
-
This behaviour makes difficult testing the job `discard_on/retry_on` logic.
|
122
|
-
|
123
|
-
Now `deserialize_arguments_if_needed` call is postponed to when `perform_now`
|
124
|
-
is called.
|
125
|
-
|
126
|
-
Example:
|
18
|
+
A common mistake with Active Job is to enqueue jobs from inside a transaction,
|
19
|
+
causing them to potentially be picked and ran by another process, before the
|
20
|
+
transaction is committed, which may result in various errors.
|
127
21
|
|
128
22
|
```ruby
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
def perform(user)
|
133
|
-
# ...
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
# In the test
|
138
|
-
User.destroy_all
|
139
|
-
assert_nothing_raised do
|
140
|
-
perform_enqueued_jobs only: UpdateUserJob
|
23
|
+
Topic.transaction do
|
24
|
+
topic = Topic.create(...)
|
25
|
+
NewTopicNotificationJob.perform_later(topic)
|
141
26
|
end
|
142
27
|
```
|
143
28
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
## Rails 7.0.0 (December 15, 2021) ##
|
148
|
-
|
149
|
-
* No changes.
|
29
|
+
Now Active Job will automatically defer the enqueuing to after the transaction is committed,
|
30
|
+
and drop the job if the transaction is rolled back.
|
150
31
|
|
32
|
+
Various queue implementations can choose to disable this behavior, and users can disable it,
|
33
|
+
or force it on a per job basis:
|
151
34
|
|
152
|
-
|
35
|
+
```ruby
|
36
|
+
class NewTopicNotificationJob < ApplicationJob
|
37
|
+
self.enqueue_after_transaction_commit = :never # or `:always` or `:default`
|
38
|
+
end
|
39
|
+
```
|
153
40
|
|
154
|
-
*
|
41
|
+
*Jean Boussier*, *Cristian Bica*
|
155
42
|
|
43
|
+
* Do not trigger immediate loading of `ActiveJob::Base` when loading `ActiveJob::TestHelper`.
|
156
44
|
|
157
|
-
|
45
|
+
*Maxime Réty*
|
158
46
|
|
159
|
-
*
|
47
|
+
* Preserve the serialized timezone when deserializing `ActiveSupport::TimeWithZone` arguments.
|
160
48
|
|
161
|
-
|
49
|
+
*Joshua Young*
|
162
50
|
|
163
|
-
* Remove deprecated `:
|
51
|
+
* Remove deprecated `:exponentially_longer` value for the `:wait` in `retry_on`.
|
164
52
|
|
165
53
|
*Rafael Mendonça França*
|
166
54
|
|
167
|
-
*
|
55
|
+
* Remove deprecated support to set numeric values to `scheduled_at` attribute.
|
168
56
|
|
169
57
|
*Rafael Mendonça França*
|
170
58
|
|
171
|
-
*
|
172
|
-
previous callback was halted with `throw :abort`.
|
59
|
+
* Deprecate `Rails.application.config.active_job.use_big_decimal_serialize`.
|
173
60
|
|
174
61
|
*Rafael Mendonça França*
|
175
62
|
|
176
|
-
*
|
177
|
-
if the module name is not present.
|
178
|
-
|
179
|
-
*Veerpal Brar*
|
180
|
-
|
181
|
-
|
182
|
-
## Rails 7.0.0.alpha2 (September 15, 2021) ##
|
183
|
-
|
184
|
-
* No changes.
|
185
|
-
|
186
|
-
|
187
|
-
## Rails 7.0.0.alpha1 (September 15, 2021) ##
|
188
|
-
|
189
|
-
* Allow a job to retry indefinitely
|
190
|
-
|
191
|
-
The `attempts` parameter of the `retry_on` method now accepts the
|
192
|
-
symbol reference `:unlimited` in addition to a specific number of retry
|
193
|
-
attempts to allow a developer to specify that a job should retry
|
194
|
-
forever until it succeeds.
|
195
|
-
|
196
|
-
class MyJob < ActiveJob::Base
|
197
|
-
retry_on(AlwaysRetryException, attempts: :unlimited)
|
198
|
-
|
199
|
-
# the actual job code
|
200
|
-
end
|
201
|
-
|
202
|
-
*Daniel Morton*
|
203
|
-
|
204
|
-
* Added possibility to check on `:priority` in test helper methods
|
205
|
-
`assert_enqueued_with` and `assert_performed_with`.
|
206
|
-
|
207
|
-
*Wojciech Wnętrzak*
|
208
|
-
|
209
|
-
* OpenSSL constants are now used for Digest computations.
|
210
|
-
|
211
|
-
*Dirkjan Bussink*
|
212
|
-
|
213
|
-
* Add a Serializer for the Range class.
|
214
|
-
|
215
|
-
This should allow things like `MyJob.perform_later(range: 1..100)`.
|
216
|
-
|
217
|
-
* Communicate enqueue failures to callers of `perform_later`.
|
218
|
-
|
219
|
-
`perform_later` can now optionally take a block which will execute after
|
220
|
-
the adapter attempts to enqueue the job. The block will receive the job
|
221
|
-
instance as an argument even if the enqueue was not successful.
|
222
|
-
Additionally, `ActiveJob` adapters now have the ability to raise an
|
223
|
-
`ActiveJob::EnqueueError` which will be caught and stored in the job
|
224
|
-
instance so code attempting to enqueue jobs can inspect any raised
|
225
|
-
`EnqueueError` using the block.
|
226
|
-
|
227
|
-
MyJob.perform_later do |job|
|
228
|
-
unless job.successfully_enqueued?
|
229
|
-
if job.enqueue_error&.message == "Redis was unavailable"
|
230
|
-
# invoke some code that will retry the job after a delay
|
231
|
-
end
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
*Daniel Morton*
|
236
|
-
|
237
|
-
* Don't log rescuable exceptions defined with `rescue_from`.
|
238
|
-
|
239
|
-
*Hu Hailin*
|
240
|
-
|
241
|
-
* Allow `rescue_from` to rescue all exceptions.
|
242
|
-
|
243
|
-
*Adrianna Chang*, *Étienne Barrié*
|
63
|
+
* Remove deprecated primitive serializer for `BigDecimal` arguments.
|
244
64
|
|
65
|
+
*Rafael Mendonça França*
|
245
66
|
|
246
|
-
Please check [
|
67
|
+
Please check [7-1-stable](https://github.com/rails/rails/blob/7-1-stable/activejob/CHANGELOG.md) for previous changes.
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -10,14 +10,14 @@ 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
|
-
The main point is to ensure that all Rails apps will have a job infrastructure
|
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
|
15
15
|
framework features and other gems build on top of that, without having to worry
|
16
16
|
about API differences between Delayed Job and Resque. Picking your queuing
|
17
17
|
backend becomes more of an operational concern, then. And you'll be able to
|
18
18
|
switch between them without having to rewrite your jobs.
|
19
19
|
|
20
|
-
You can read more about Active Job in the [Active Job Basics](https://
|
20
|
+
You can read more about Active Job in the [Active Job Basics](https://guides.rubyonrails.org/active_job_basics.html) guide.
|
21
21
|
|
22
22
|
## Usage
|
23
23
|
|
data/lib/active_job/arguments.rb
CHANGED
@@ -46,8 +46,6 @@ module ActiveJob
|
|
46
46
|
end
|
47
47
|
|
48
48
|
private
|
49
|
-
# :nodoc:
|
50
|
-
PERMITTED_TYPES = [ NilClass, String, Integer, Float, BigDecimal, TrueClass, FalseClass ]
|
51
49
|
# :nodoc:
|
52
50
|
GLOBALID_KEY = "_aj_globalid"
|
53
51
|
# :nodoc:
|
@@ -67,35 +65,23 @@ module ActiveJob
|
|
67
65
|
OBJECT_SERIALIZER_KEY, OBJECT_SERIALIZER_KEY.to_sym,
|
68
66
|
WITH_INDIFFERENT_ACCESS_KEY, WITH_INDIFFERENT_ACCESS_KEY.to_sym,
|
69
67
|
]
|
70
|
-
private_constant :
|
68
|
+
private_constant :RESERVED_KEYS, :GLOBALID_KEY,
|
71
69
|
:SYMBOL_KEYS_KEY, :RUBY2_KEYWORDS_KEY, :WITH_INDIFFERENT_ACCESS_KEY
|
72
70
|
|
73
|
-
unless Hash.respond_to?(:ruby2_keywords_hash?) && Hash.respond_to?(:ruby2_keywords_hash)
|
74
|
-
using Module.new {
|
75
|
-
refine Hash do
|
76
|
-
class << Hash
|
77
|
-
def ruby2_keywords_hash?(hash)
|
78
|
-
!new(*[hash]).default.equal?(hash)
|
79
|
-
end
|
80
|
-
|
81
|
-
def ruby2_keywords_hash(hash)
|
82
|
-
_ruby2_keywords_hash(**hash)
|
83
|
-
end
|
84
|
-
|
85
|
-
private
|
86
|
-
def _ruby2_keywords_hash(*args)
|
87
|
-
args.last
|
88
|
-
end
|
89
|
-
ruby2_keywords(:_ruby2_keywords_hash)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
}
|
93
|
-
end
|
94
|
-
|
95
71
|
def serialize_argument(argument)
|
96
72
|
case argument
|
97
|
-
when
|
73
|
+
when nil, true, false, Integer, Float # Types that can hardly be subclassed
|
98
74
|
argument
|
75
|
+
when String
|
76
|
+
if argument.class == String
|
77
|
+
argument
|
78
|
+
else
|
79
|
+
begin
|
80
|
+
Serializers.serialize(argument)
|
81
|
+
rescue SerializationError
|
82
|
+
argument
|
83
|
+
end
|
84
|
+
end
|
99
85
|
when GlobalID::Identification
|
100
86
|
convert_to_global_id_hash(argument)
|
101
87
|
when Array
|
@@ -112,18 +98,18 @@ module ActiveJob
|
|
112
98
|
result = serialize_hash(argument)
|
113
99
|
result[aj_hash_key] = symbol_keys
|
114
100
|
result
|
115
|
-
when -> (arg) { arg.respond_to?(:permitted?) && arg.respond_to?(:to_h) }
|
116
|
-
serialize_indifferent_hash(argument.to_h)
|
117
101
|
else
|
118
|
-
|
102
|
+
if argument.respond_to?(:permitted?) && argument.respond_to?(:to_h)
|
103
|
+
serialize_indifferent_hash(argument.to_h)
|
104
|
+
else
|
105
|
+
Serializers.serialize(argument)
|
106
|
+
end
|
119
107
|
end
|
120
108
|
end
|
121
109
|
|
122
110
|
def deserialize_argument(argument)
|
123
111
|
case argument
|
124
|
-
when String
|
125
|
-
argument
|
126
|
-
when *PERMITTED_TYPES
|
112
|
+
when nil, true, false, String, Integer, Float
|
127
113
|
argument
|
128
114
|
when Array
|
129
115
|
argument.map { |arg| deserialize_argument(arg) }
|
data/lib/active_job/base.rb
CHANGED
@@ -15,7 +15,7 @@ require "active_job/timezones"
|
|
15
15
|
require "active_job/translation"
|
16
16
|
|
17
17
|
module ActiveJob # :nodoc:
|
18
|
-
# = Active Job
|
18
|
+
# = Active Job \Base
|
19
19
|
#
|
20
20
|
# Active Job objects can be configured to work with different backend
|
21
21
|
# queuing frameworks. To specify a queue adapter to use:
|
data/lib/active_job/callbacks.rb
CHANGED
@@ -4,7 +4,7 @@ require "active_support/callbacks"
|
|
4
4
|
require "active_support/core_ext/module/attribute_accessors"
|
5
5
|
|
6
6
|
module ActiveJob
|
7
|
-
# = Active Job Callbacks
|
7
|
+
# = Active Job \Callbacks
|
8
8
|
#
|
9
9
|
# Active Job provides hooks during the life cycle of a job. Callbacks allow you
|
10
10
|
# to trigger logic during this cycle. Available callbacks are:
|
@@ -15,9 +15,6 @@ module ActiveJob
|
|
15
15
|
# * <tt>before_perform</tt>
|
16
16
|
# * <tt>around_perform</tt>
|
17
17
|
# * <tt>after_perform</tt>
|
18
|
-
#
|
19
|
-
# NOTE: Calling the same callback multiple times will overwrite previous callback definitions.
|
20
|
-
#
|
21
18
|
module Callbacks
|
22
19
|
extend ActiveSupport::Concern
|
23
20
|
include ActiveSupport::Callbacks
|
@@ -28,9 +25,6 @@ module ActiveJob
|
|
28
25
|
end
|
29
26
|
|
30
27
|
included do
|
31
|
-
cattr_accessor :skip_after_callbacks_if_terminated, instance_accessor: false, default: false
|
32
|
-
singleton_class.deprecate :skip_after_callbacks_if_terminated, :skip_after_callbacks_if_terminated=
|
33
|
-
|
34
28
|
define_callbacks :perform, skip_after_callbacks_if_terminated: true
|
35
29
|
define_callbacks :enqueue, skip_after_callbacks_if_terminated: true
|
36
30
|
end
|
@@ -135,7 +129,8 @@ module ActiveJob
|
|
135
129
|
# queue_as :default
|
136
130
|
#
|
137
131
|
# after_enqueue do |job|
|
138
|
-
#
|
132
|
+
# result = job.successfully_enqueued? ? "success" : "failure"
|
133
|
+
# $statsd.increment "enqueue-video-job.#{result}"
|
139
134
|
# end
|
140
135
|
#
|
141
136
|
# def perform(video_id)
|
data/lib/active_job/core.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveJob
|
4
|
+
# = Active Job \Core
|
5
|
+
#
|
4
6
|
# Provides general behavior that will be included into every Active Job
|
5
7
|
# object that inherits from ActiveJob::Base.
|
6
8
|
module Core
|
@@ -10,7 +12,7 @@ module ActiveJob
|
|
10
12
|
attr_accessor :arguments
|
11
13
|
attr_writer :serialized_arguments
|
12
14
|
|
13
|
-
#
|
15
|
+
# Time when the job should be performed
|
14
16
|
attr_accessor :scheduled_at
|
15
17
|
|
16
18
|
# Job Identifier
|
@@ -92,6 +94,7 @@ module ActiveJob
|
|
92
94
|
@arguments = arguments
|
93
95
|
@job_id = SecureRandom.uuid
|
94
96
|
@queue_name = self.class.queue_name
|
97
|
+
@scheduled_at = nil
|
95
98
|
@priority = self.class.priority
|
96
99
|
@executions = 0
|
97
100
|
@exception_executions = {}
|
@@ -113,7 +116,8 @@ module ActiveJob
|
|
113
116
|
"exception_executions" => exception_executions,
|
114
117
|
"locale" => I18n.locale.to_s,
|
115
118
|
"timezone" => timezone,
|
116
|
-
"enqueued_at" => Time.now.utc.iso8601
|
119
|
+
"enqueued_at" => Time.now.utc.iso8601(9),
|
120
|
+
"scheduled_at" => scheduled_at ? scheduled_at.utc.iso8601(9) : nil,
|
117
121
|
}
|
118
122
|
end
|
119
123
|
|
@@ -153,13 +157,14 @@ module ActiveJob
|
|
153
157
|
self.exception_executions = job_data["exception_executions"]
|
154
158
|
self.locale = job_data["locale"] || I18n.locale.to_s
|
155
159
|
self.timezone = job_data["timezone"] || Time.zone&.name
|
156
|
-
self.enqueued_at = job_data["enqueued_at"]
|
160
|
+
self.enqueued_at = Time.iso8601(job_data["enqueued_at"]) if job_data["enqueued_at"]
|
161
|
+
self.scheduled_at = Time.iso8601(job_data["scheduled_at"]) if job_data["scheduled_at"]
|
157
162
|
end
|
158
163
|
|
159
164
|
# Configures the job with the given options.
|
160
165
|
def set(options = {}) # :nodoc:
|
161
|
-
self.scheduled_at = options[:wait].seconds.from_now
|
162
|
-
self.scheduled_at = options[:wait_until]
|
166
|
+
self.scheduled_at = options[:wait].seconds.from_now if options[:wait]
|
167
|
+
self.scheduled_at = options[:wait_until] if options[:wait_until]
|
163
168
|
self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue]
|
164
169
|
self.priority = options[:priority].to_i if options[:priority]
|
165
170
|
|
@@ -191,7 +196,7 @@ module ActiveJob
|
|
191
196
|
end
|
192
197
|
|
193
198
|
def arguments_serialized?
|
194
|
-
|
199
|
+
@serialized_arguments
|
195
200
|
end
|
196
201
|
end
|
197
202
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveJob
|
4
|
+
module EnqueueAfterTransactionCommit # :nodoc:
|
5
|
+
private
|
6
|
+
def raw_enqueue
|
7
|
+
after_transaction = case self.class.enqueue_after_transaction_commit
|
8
|
+
when :always
|
9
|
+
true
|
10
|
+
when :never
|
11
|
+
false
|
12
|
+
else # :default
|
13
|
+
queue_adapter.enqueue_after_transaction_commit?
|
14
|
+
end
|
15
|
+
|
16
|
+
if after_transaction
|
17
|
+
self.successfully_enqueued = true
|
18
|
+
ActiveRecord.after_all_transactions_commit do
|
19
|
+
self.successfully_enqueued = false
|
20
|
+
super
|
21
|
+
end
|
22
|
+
self
|
23
|
+
else
|
24
|
+
super
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/active_job/enqueuing.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "active_job/arguments"
|
4
|
-
|
5
3
|
module ActiveJob
|
6
4
|
# Provides behavior for enqueuing jobs.
|
7
5
|
|
@@ -9,9 +7,53 @@ module ActiveJob
|
|
9
7
|
# why the adapter was unexpectedly unable to enqueue a job.
|
10
8
|
class EnqueueError < StandardError; end
|
11
9
|
|
10
|
+
class << self
|
11
|
+
# Push many jobs onto the queue at once without running enqueue callbacks.
|
12
|
+
# Queue adapters may communicate the enqueue status of each job by setting
|
13
|
+
# successfully_enqueued and/or enqueue_error on the passed-in job instances.
|
14
|
+
def perform_all_later(*jobs)
|
15
|
+
jobs.flatten!
|
16
|
+
jobs.group_by(&:queue_adapter).each do |queue_adapter, adapter_jobs|
|
17
|
+
instrument_enqueue_all(queue_adapter, adapter_jobs) do
|
18
|
+
if queue_adapter.respond_to?(:enqueue_all)
|
19
|
+
queue_adapter.enqueue_all(adapter_jobs)
|
20
|
+
else
|
21
|
+
adapter_jobs.each do |job|
|
22
|
+
job.successfully_enqueued = false
|
23
|
+
if job.scheduled_at
|
24
|
+
queue_adapter.enqueue_at(job, job.scheduled_at.to_f)
|
25
|
+
else
|
26
|
+
queue_adapter.enqueue(job)
|
27
|
+
end
|
28
|
+
job.successfully_enqueued = true
|
29
|
+
rescue EnqueueError => e
|
30
|
+
job.enqueue_error = e
|
31
|
+
end
|
32
|
+
adapter_jobs.count(&:successfully_enqueued?)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
12
40
|
module Enqueuing
|
13
41
|
extend ActiveSupport::Concern
|
14
42
|
|
43
|
+
included do
|
44
|
+
##
|
45
|
+
# :singleton-method:
|
46
|
+
#
|
47
|
+
# Defines if enqueueing this job from inside an Active Record transaction
|
48
|
+
# automatically defers the enqueue to after the transaction commits.
|
49
|
+
#
|
50
|
+
# It can be set on a per job basis:
|
51
|
+
# - `:always` forces the job to be deferred.
|
52
|
+
# - `:never` forces the job to be queued immediately.
|
53
|
+
# - `:default` lets the queue adapter define the behavior (recommended).
|
54
|
+
class_attribute :enqueue_after_transaction_commit, instance_accessor: false, instance_predicate: false, default: :never
|
55
|
+
end
|
56
|
+
|
15
57
|
# Includes the +perform_later+ method for job initialization.
|
16
58
|
module ClassMethods
|
17
59
|
# Push a job onto the queue. By default the arguments must be either String,
|
@@ -22,9 +64,21 @@ module ActiveJob
|
|
22
64
|
# custom serializers.
|
23
65
|
#
|
24
66
|
# Returns an instance of the job class queued with arguments available in
|
25
|
-
# Job#arguments or false if the enqueue did not succeed.
|
67
|
+
# Job#arguments or +false+ if the enqueue did not succeed.
|
26
68
|
#
|
27
69
|
# After the attempted enqueue, the job will be yielded to an optional block.
|
70
|
+
#
|
71
|
+
# If Active Job is used conjointly with Active Record, and #perform_later is called
|
72
|
+
# inside an Active Record transaction, then the enqueue is implicitly deferred to after
|
73
|
+
# the transaction is committed, or dropped if it's rolled back. In such case #perform_later
|
74
|
+
# will return the job instance like if it was successfully enqueued, but will still return
|
75
|
+
# +false+ if a callback prevented the job from being enqueued.
|
76
|
+
#
|
77
|
+
# This behavior can be changed on a per job basis:
|
78
|
+
#
|
79
|
+
# class NotificationJob < ApplicationJob
|
80
|
+
# self.enqueue_after_transaction_commit = false
|
81
|
+
# end
|
28
82
|
def perform_later(...)
|
29
83
|
job = job_or_instantiate(...)
|
30
84
|
enqueue_result = job.enqueue
|
@@ -35,7 +89,7 @@ module ActiveJob
|
|
35
89
|
end
|
36
90
|
|
37
91
|
private
|
38
|
-
def job_or_instantiate(*args) # :doc:
|
92
|
+
def job_or_instantiate(*args, &_) # :doc:
|
39
93
|
args.first.is_a?(self) ? args.first : new(*args)
|
40
94
|
end
|
41
95
|
ruby2_keywords(:job_or_instantiate)
|
@@ -61,8 +115,20 @@ module ActiveJob
|
|
61
115
|
self.successfully_enqueued = false
|
62
116
|
|
63
117
|
run_callbacks :enqueue do
|
118
|
+
raw_enqueue
|
119
|
+
end
|
120
|
+
|
121
|
+
if successfully_enqueued?
|
122
|
+
self
|
123
|
+
else
|
124
|
+
false
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
private
|
129
|
+
def raw_enqueue
|
64
130
|
if scheduled_at
|
65
|
-
queue_adapter.enqueue_at self, scheduled_at
|
131
|
+
queue_adapter.enqueue_at self, scheduled_at.to_f
|
66
132
|
else
|
67
133
|
queue_adapter.enqueue self
|
68
134
|
end
|
@@ -71,12 +137,5 @@ module ActiveJob
|
|
71
137
|
rescue EnqueueError => e
|
72
138
|
self.enqueue_error = e
|
73
139
|
end
|
74
|
-
|
75
|
-
if successfully_enqueued?
|
76
|
-
self
|
77
|
-
else
|
78
|
-
false
|
79
|
-
end
|
80
|
-
end
|
81
140
|
end
|
82
141
|
end
|