activejob 7.1.0.beta1 → 7.1.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/lib/active_job/core.rb +24 -6
- data/lib/active_job/enqueuing.rb +2 -2
- data/lib/active_job/exceptions.rb +18 -5
- data/lib/active_job/gem_version.rb +1 -1
- data/lib/active_job/log_subscriber.rb +1 -1
- data/lib/active_job/queue_adapters/sidekiq_adapter.rb +1 -1
- data/lib/active_job/queue_adapters/test_adapter.rb +1 -1
- data/lib/active_job/test_helper.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d95076eb165c16b44e30c4f98c72bce402b3124c5754e76ad6b86f1e4e02b81e
|
4
|
+
data.tar.gz: e9f4bb0bd99471a34abd21723776a66913b593c605dcd8f84079c029f74cfbc7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70fc9872437f7ebb6161686b3b4ed66acd79e8d1b3e750f84384f1818ea213c0a1b038a9b435cc6c727790eb2334d7ea2458810e90b321485b25dec6c6c3d944
|
7
|
+
data.tar.gz: ea5ae1a2c0ae70db9c44935f7da32344fd84519de9e7b570815f7194e0b780a6c9aba811128a8740fbefac252e2844760bf7c6aec62653fc84dc86f24fdf8adb
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
## Rails 7.1.0.rc2 (October 01, 2023) ##
|
2
|
+
|
3
|
+
* Make sure `scheduled_at` is a Time object when asserting enqueued jobs.
|
4
|
+
|
5
|
+
*Rafael Mendonça França*
|
6
|
+
|
7
|
+
|
8
|
+
## Rails 7.1.0.rc1 (September 27, 2023) ##
|
9
|
+
|
10
|
+
* Set `scheduled_at` attribute as a Time object instead of epoch seconds, and serialize and deserialize the value
|
11
|
+
when enqueued. Assigning a numeric/epoch value to scheduled_at= is deprecated; use a Time object instead.
|
12
|
+
|
13
|
+
Deserializes `enqueued_at` as a Time instead of ISO8601 String.
|
14
|
+
|
15
|
+
*Ben Sheldon*
|
16
|
+
|
17
|
+
* Clarify the backoff strategy for the recommended `:wait` option when retrying jobs
|
18
|
+
|
19
|
+
`wait: :exponentially_longer` is waiting polynomially longer, so it is now recommended to use `wait: :polynomially_longer` to keep the same behavior.
|
20
|
+
|
21
|
+
*Victor Mours*
|
22
|
+
|
23
|
+
|
1
24
|
## Rails 7.1.0.beta1 (September 13, 2023) ##
|
2
25
|
|
3
26
|
* Fix Active Job log message to correctly report a job failed to enqueue
|
data/lib/active_job/core.rb
CHANGED
@@ -12,8 +12,10 @@ module ActiveJob
|
|
12
12
|
attr_accessor :arguments
|
13
13
|
attr_writer :serialized_arguments
|
14
14
|
|
15
|
-
#
|
16
|
-
|
15
|
+
# Time when the job should be performed
|
16
|
+
attr_reader :scheduled_at
|
17
|
+
|
18
|
+
attr_reader :_scheduled_at_time # :nodoc:
|
17
19
|
|
18
20
|
# Job Identifier
|
19
21
|
attr_accessor :job_id
|
@@ -94,6 +96,8 @@ module ActiveJob
|
|
94
96
|
@arguments = arguments
|
95
97
|
@job_id = SecureRandom.uuid
|
96
98
|
@queue_name = self.class.queue_name
|
99
|
+
@scheduled_at = nil
|
100
|
+
@_scheduled_at_time = nil
|
97
101
|
@priority = self.class.priority
|
98
102
|
@executions = 0
|
99
103
|
@exception_executions = {}
|
@@ -115,7 +119,8 @@ module ActiveJob
|
|
115
119
|
"exception_executions" => exception_executions,
|
116
120
|
"locale" => I18n.locale.to_s,
|
117
121
|
"timezone" => timezone,
|
118
|
-
"enqueued_at" => Time.now.utc.iso8601(9)
|
122
|
+
"enqueued_at" => Time.now.utc.iso8601(9),
|
123
|
+
"scheduled_at" => _scheduled_at_time ? _scheduled_at_time.utc.iso8601(9) : nil,
|
119
124
|
}
|
120
125
|
end
|
121
126
|
|
@@ -155,19 +160,32 @@ module ActiveJob
|
|
155
160
|
self.exception_executions = job_data["exception_executions"]
|
156
161
|
self.locale = job_data["locale"] || I18n.locale.to_s
|
157
162
|
self.timezone = job_data["timezone"] || Time.zone&.name
|
158
|
-
self.enqueued_at = job_data["enqueued_at"]
|
163
|
+
self.enqueued_at = Time.iso8601(job_data["enqueued_at"]) if job_data["enqueued_at"]
|
164
|
+
self.scheduled_at = Time.iso8601(job_data["scheduled_at"]) if job_data["scheduled_at"]
|
159
165
|
end
|
160
166
|
|
161
167
|
# Configures the job with the given options.
|
162
168
|
def set(options = {}) # :nodoc:
|
163
|
-
self.scheduled_at = options[:wait].seconds.from_now
|
164
|
-
self.scheduled_at = options[:wait_until]
|
169
|
+
self.scheduled_at = options[:wait].seconds.from_now if options[:wait]
|
170
|
+
self.scheduled_at = options[:wait_until] if options[:wait_until]
|
165
171
|
self.queue_name = self.class.queue_name_from_part(options[:queue]) if options[:queue]
|
166
172
|
self.priority = options[:priority].to_i if options[:priority]
|
167
173
|
|
168
174
|
self
|
169
175
|
end
|
170
176
|
|
177
|
+
def scheduled_at=(value)
|
178
|
+
@_scheduled_at_time = if value&.is_a?(Numeric)
|
179
|
+
ActiveJob.deprecator.warn(<<~MSG.squish)
|
180
|
+
Assigning a numeric/epoch value to scheduled_at is deprecated. Use a Time object instead.
|
181
|
+
MSG
|
182
|
+
Time.at(value)
|
183
|
+
else
|
184
|
+
value
|
185
|
+
end
|
186
|
+
@scheduled_at = value
|
187
|
+
end
|
188
|
+
|
171
189
|
private
|
172
190
|
def serialize_arguments_if_needed(arguments)
|
173
191
|
if arguments_serialized?
|
data/lib/active_job/enqueuing.rb
CHANGED
@@ -23,7 +23,7 @@ module ActiveJob
|
|
23
23
|
adapter_jobs.each do |job|
|
24
24
|
job.successfully_enqueued = false
|
25
25
|
if job.scheduled_at
|
26
|
-
queue_adapter.enqueue_at(job, job.
|
26
|
+
queue_adapter.enqueue_at(job, job._scheduled_at_time.to_f)
|
27
27
|
else
|
28
28
|
queue_adapter.enqueue(job)
|
29
29
|
end
|
@@ -92,7 +92,7 @@ module ActiveJob
|
|
92
92
|
|
93
93
|
run_callbacks :enqueue do
|
94
94
|
if scheduled_at
|
95
|
-
queue_adapter.enqueue_at self,
|
95
|
+
queue_adapter.enqueue_at self, _scheduled_at_time.to_f
|
96
96
|
else
|
97
97
|
queue_adapter.enqueue self
|
98
98
|
end
|
@@ -21,10 +21,13 @@ module ActiveJob
|
|
21
21
|
# You can also pass a block that'll be invoked if the retry attempts fail for custom logic rather than letting
|
22
22
|
# the exception bubble up. This block is yielded with the job instance as the first and the error instance as the second parameter.
|
23
23
|
#
|
24
|
+
# `retry_on` and `discard_on` handlers are searched from bottom to top, and up the class hierarchy. The handler of the first class for
|
25
|
+
# which <tt>exception.is_a?(klass)</tt> holds true is the one invoked, if any.
|
26
|
+
#
|
24
27
|
# ==== Options
|
25
28
|
# * <tt>:wait</tt> - Re-enqueues the job with a delay specified either in seconds (default: 3 seconds),
|
26
29
|
# as a computing proc that takes the number of executions so far as an argument, or as a symbol reference of
|
27
|
-
# <tt>:
|
30
|
+
# <tt>:polynomially_longer</tt>, which applies the wait algorithm of <tt>((executions**4) + (Kernel.rand * (executions**4) * jitter)) + 2</tt>
|
28
31
|
# (first wait ~3s, then ~18s, then ~83s, etc)
|
29
32
|
# * <tt>:attempts</tt> - Re-enqueues the job the specified number of times (default: 5 attempts) or a symbol reference of <tt>:unlimited</tt>
|
30
33
|
# to retry the job until it succeeds
|
@@ -40,11 +43,11 @@ module ActiveJob
|
|
40
43
|
# retry_on CustomInfrastructureException, wait: 5.minutes, attempts: :unlimited
|
41
44
|
#
|
42
45
|
# retry_on ActiveRecord::Deadlocked, wait: 5.seconds, attempts: 3
|
43
|
-
# retry_on Net::OpenTimeout, Timeout::Error, wait: :
|
46
|
+
# retry_on Net::OpenTimeout, Timeout::Error, wait: :polynomially_longer, attempts: 10 # retries at most 10 times for Net::OpenTimeout and Timeout::Error combined
|
44
47
|
# # To retry at most 10 times for each individual exception:
|
45
|
-
# # retry_on Net::OpenTimeout, wait: :
|
48
|
+
# # retry_on Net::OpenTimeout, wait: :polynomially_longer, attempts: 10
|
46
49
|
# # retry_on Net::ReadTimeout, wait: 5.seconds, jitter: 0.30, attempts: 10
|
47
|
-
# # retry_on Timeout::Error, wait: :
|
50
|
+
# # retry_on Timeout::Error, wait: :polynomially_longer, attempts: 10
|
48
51
|
#
|
49
52
|
# retry_on(YetAnotherCustomAppException) do |job, error|
|
50
53
|
# ExceptionNotifier.caught(error)
|
@@ -57,6 +60,12 @@ module ActiveJob
|
|
57
60
|
# end
|
58
61
|
# end
|
59
62
|
def retry_on(*exceptions, wait: 3.seconds, attempts: 5, queue: nil, priority: nil, jitter: JITTER_DEFAULT)
|
63
|
+
if wait == :exponentially_longer
|
64
|
+
ActiveJob.deprecator.warn(<<~MSG.squish)
|
65
|
+
`wait: :exponentially_longer` will actually wait polynomially longer and is therefore deprecated.
|
66
|
+
Prefer `wait: :polynomially_longer` to avoid confusion and keep the same behavior.
|
67
|
+
MSG
|
68
|
+
end
|
60
69
|
rescue_from(*exceptions) do |error|
|
61
70
|
executions = executions_for(exceptions)
|
62
71
|
if attempts == :unlimited || executions < attempts
|
@@ -81,6 +90,9 @@ module ActiveJob
|
|
81
90
|
#
|
82
91
|
# You can also pass a block that'll be invoked. This block is yielded with the job instance as the first and the error instance as the second parameter.
|
83
92
|
#
|
93
|
+
# `retry_on` and `discard_on` handlers are searched from bottom to top, and up the class hierarchy. The handler of the first class for
|
94
|
+
# which <tt>exception.is_a?(klass)</tt> holds true is the one invoked, if any.
|
95
|
+
#
|
84
96
|
# ==== Example
|
85
97
|
#
|
86
98
|
# class SearchIndexingJob < ActiveJob::Base
|
@@ -156,7 +168,8 @@ module ActiveJob
|
|
156
168
|
jitter = jitter == JITTER_DEFAULT ? self.class.retry_jitter : (jitter || 0.0)
|
157
169
|
|
158
170
|
case seconds_or_duration_or_algorithm
|
159
|
-
when :exponentially_longer
|
171
|
+
when :exponentially_longer, :polynomially_longer
|
172
|
+
# This delay uses a polynomial backoff strategy, which was previously misnamed as exponential
|
160
173
|
delay = executions**4
|
161
174
|
delay_jitter = determine_jitter_for_delay(delay, jitter)
|
162
175
|
delay + delay_jitter + 2
|
@@ -76,7 +76,7 @@ module ActiveJob
|
|
76
76
|
def perform_start(event)
|
77
77
|
info do
|
78
78
|
job = event.payload[:job]
|
79
|
-
"Performing #{job.class.name} (Job ID: #{job.job_id}) from #{queue_name(event)} enqueued at #{job.enqueued_at}" + args_info(job)
|
79
|
+
"Performing #{job.class.name} (Job ID: #{job.job_id}) from #{queue_name(event)} enqueued at #{job.enqueued_at.utc.iso8601(9)}" + args_info(job)
|
80
80
|
end
|
81
81
|
end
|
82
82
|
subscribe_log_level :perform_start, :info
|
@@ -54,7 +54,7 @@ module ActiveJob
|
|
54
54
|
"wrapped" => job_class,
|
55
55
|
"queue" => queue,
|
56
56
|
"args" => scheduled_jobs.map { |job| [job.serialize] },
|
57
|
-
"at" => scheduled_jobs.map { |job| job.scheduled_at }
|
57
|
+
"at" => scheduled_jobs.map { |job| job.scheduled_at&.to_f }
|
58
58
|
)
|
59
59
|
enqueued_count += jids.compact.size
|
60
60
|
end
|
@@ -730,7 +730,7 @@ module ActiveJob
|
|
730
730
|
|
731
731
|
def instantiate_job(payload, skip_deserialize_arguments: false)
|
732
732
|
job = payload[:job].deserialize(payload)
|
733
|
-
job.scheduled_at = payload[:at]
|
733
|
+
job.scheduled_at = Time.at(payload[:at]) if payload.key?(:at)
|
734
734
|
job.send(:deserialize_arguments_if_needed) unless skip_deserialize_arguments
|
735
735
|
job
|
736
736
|
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: 7.1.0.
|
4
|
+
version: 7.1.0.rc2
|
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: 2023-
|
11
|
+
date: 2023-10-01 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: 7.1.0.
|
19
|
+
version: 7.1.0.rc2
|
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: 7.1.0.
|
26
|
+
version: 7.1.0.rc2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: globalid
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,10 +102,10 @@ licenses:
|
|
102
102
|
- MIT
|
103
103
|
metadata:
|
104
104
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
105
|
-
changelog_uri: https://github.com/rails/rails/blob/v7.1.0.
|
106
|
-
documentation_uri: https://api.rubyonrails.org/v7.1.0.
|
105
|
+
changelog_uri: https://github.com/rails/rails/blob/v7.1.0.rc2/activejob/CHANGELOG.md
|
106
|
+
documentation_uri: https://api.rubyonrails.org/v7.1.0.rc2/
|
107
107
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
108
|
-
source_code_uri: https://github.com/rails/rails/tree/v7.1.0.
|
108
|
+
source_code_uri: https://github.com/rails/rails/tree/v7.1.0.rc2/activejob
|
109
109
|
rubygems_mfa_required: 'true'
|
110
110
|
post_install_message:
|
111
111
|
rdoc_options: []
|