未验证 提交 48375319 编写于 作者: R Rafael França 提交者: GitHub

Merge pull request #34890 from rosa/test-exceptions-with-all-adapters

Run exception tests for all ActiveJob adapters and fix issue with individual counters and Resque
......@@ -81,7 +81,7 @@ def initialize(*arguments)
@queue_name = self.class.queue_name
@priority = self.class.priority
@executions = 0
@exception_executions = Hash.new(0)
@exception_executions = {}
end
# Returns a hash with the job data that can safely be passed to the
......
......@@ -50,8 +50,8 @@ module ClassMethods
def retry_on(*exceptions, wait: 3.seconds, attempts: 5, queue: nil, priority: nil)
rescue_from(*exceptions) do |error|
# Guard against jobs that were persisted before we started having individual executions counters per retry_on
self.exception_executions ||= Hash.new(0)
self.exception_executions[exceptions.to_s] += 1
self.exception_executions ||= {}
self.exception_executions[exceptions.to_s] = (exception_executions[exceptions.to_s] || 0) + 1
if exception_executions[exceptions.to_s] < attempts
retry_job wait: determine_delay(wait), queue: queue, priority: priority, error: error
......
......@@ -4,30 +4,26 @@
require "jobs/retry_job"
require "models/person"
class ExceptionsTest < ActiveJob::TestCase
class ExceptionsTest < ActiveSupport::TestCase
setup do
JobBuffer.clear
skip if ActiveJob::Base.queue_adapter.is_a?(ActiveJob::QueueAdapters::InlineAdapter)
skip if adapter_skips_scheduling?(ActiveJob::Base.queue_adapter)
end
test "successfully retry job throwing exception against defaults" do
perform_enqueued_jobs do
RetryJob.perform_later "DefaultsError", 5
RetryJob.perform_later "DefaultsError", 5
assert_equal [
"Raised DefaultsError for the 1st time",
"Raised DefaultsError for the 2nd time",
"Raised DefaultsError for the 3rd time",
"Raised DefaultsError for the 4th time",
"Successfully completed job" ], JobBuffer.values
end
assert_equal [
"Raised DefaultsError for the 1st time",
"Raised DefaultsError for the 2nd time",
"Raised DefaultsError for the 3rd time",
"Raised DefaultsError for the 4th time",
"Successfully completed job" ], JobBuffer.values
end
test "successfully retry job throwing exception against higher limit" do
perform_enqueued_jobs do
RetryJob.perform_later "ShortWaitTenAttemptsError", 9
assert_equal 9, JobBuffer.values.count
end
RetryJob.perform_later "ShortWaitTenAttemptsError", 9
assert_equal 9, JobBuffer.values.count
end
test "keeps the same attempts counter for several exceptions listed in the same retry_on declaration" do
......@@ -35,9 +31,7 @@ class ExceptionsTest < ActiveJob::TestCase
SecondRetryableErrorOfTwo SecondRetryableErrorOfTwo)
assert_raises SecondRetryableErrorOfTwo do
perform_enqueued_jobs do
RetryJob.perform_later(exceptions_to_raise, 5)
end
RetryJob.perform_later(exceptions_to_raise, 5)
assert_equal [
"Raised FirstRetryableErrorOfTwo for the 1st time",
......@@ -54,9 +48,7 @@ class ExceptionsTest < ActiveJob::TestCase
FirstRetryableErrorOfTwo FirstRetryableErrorOfTwo FirstRetryableErrorOfTwo)
assert_nothing_raised do
perform_enqueued_jobs do
RetryJob.perform_later(exceptions_to_raise, 10)
end
RetryJob.perform_later(exceptions_to_raise, 10)
assert_equal [
"Raised DefaultsError for the 1st time",
......@@ -72,108 +64,107 @@ class ExceptionsTest < ActiveJob::TestCase
end
test "failed retry job when exception kept occurring against defaults" do
perform_enqueued_jobs do
RetryJob.perform_later "DefaultsError", 6
assert_equal "Raised DefaultsError for the 5th time", JobBuffer.last_value
rescue DefaultsError
pass
end
RetryJob.perform_later "DefaultsError", 6
assert_equal "Raised DefaultsError for the 5th time", JobBuffer.last_value
rescue DefaultsError
pass
end
test "failed retry job when exception kept occurring against higher limit" do
perform_enqueued_jobs do
RetryJob.perform_later "ShortWaitTenAttemptsError", 11
assert_equal "Raised ShortWaitTenAttemptsError for the 10th time", JobBuffer.last_value
rescue ShortWaitTenAttemptsError
pass
end
RetryJob.perform_later "ShortWaitTenAttemptsError", 11
assert_equal "Raised ShortWaitTenAttemptsError for the 10th time", JobBuffer.last_value
rescue ShortWaitTenAttemptsError
pass
end
test "discard job" do
perform_enqueued_jobs do
RetryJob.perform_later "DiscardableError", 2
assert_equal "Raised DiscardableError for the 1st time", JobBuffer.last_value
end
RetryJob.perform_later "DiscardableError", 2
assert_equal "Raised DiscardableError for the 1st time", JobBuffer.last_value
end
test "custom handling of discarded job" do
perform_enqueued_jobs do
RetryJob.perform_later "CustomDiscardableError", 2
assert_equal "Dealt with a job that was discarded in a custom way. Message: CustomDiscardableError", JobBuffer.last_value
end
RetryJob.perform_later "CustomDiscardableError", 2
assert_equal "Dealt with a job that was discarded in a custom way. Message: CustomDiscardableError", JobBuffer.last_value
end
test "custom handling of job that exceeds retry attempts" do
perform_enqueued_jobs do
RetryJob.perform_later "CustomCatchError", 6
assert_equal "Dealt with a job that failed to retry in a custom way after 6 attempts. Message: CustomCatchError", JobBuffer.last_value
end
RetryJob.perform_later "CustomCatchError", 6
assert_equal "Dealt with a job that failed to retry in a custom way after 6 attempts. Message: CustomCatchError", JobBuffer.last_value
end
test "long wait job" do
travel_to Time.now
perform_enqueued_jobs do
assert_performed_with at: (Time.now + 3600.seconds).to_i do
RetryJob.perform_later "LongWaitError", 5
end
end
RetryJob.perform_later "LongWaitError", 2, :log_scheduled_at
assert_equal [
"Raised LongWaitError for the 1st time",
"Next execution scheduled at #{(Time.now + 3600.seconds).to_f}",
"Successfully completed job"
], JobBuffer.values
end
test "exponentially retrying job" do
travel_to Time.now
perform_enqueued_jobs do
assert_performed_with at: (Time.now + 3.seconds).to_i do
assert_performed_with at: (Time.now + 18.seconds).to_i do
assert_performed_with at: (Time.now + 83.seconds).to_i do
assert_performed_with at: (Time.now + 258.seconds).to_i do
RetryJob.perform_later "ExponentialWaitTenAttemptsError", 5
end
end
end
end
end
RetryJob.perform_later "ExponentialWaitTenAttemptsError", 5, :log_scheduled_at
assert_equal [
"Raised ExponentialWaitTenAttemptsError for the 1st time",
"Next execution scheduled at #{(Time.now + 3.seconds).to_f}",
"Raised ExponentialWaitTenAttemptsError for the 2nd time",
"Next execution scheduled at #{(Time.now + 18.seconds).to_f}",
"Raised ExponentialWaitTenAttemptsError for the 3rd time",
"Next execution scheduled at #{(Time.now + 83.seconds).to_f}",
"Raised ExponentialWaitTenAttemptsError for the 4th time",
"Next execution scheduled at #{(Time.now + 258.seconds).to_f}",
"Successfully completed job"
], JobBuffer.values
end
test "custom wait retrying job" do
travel_to Time.now
perform_enqueued_jobs do
assert_performed_with at: (Time.now + 2.seconds).to_i do
assert_performed_with at: (Time.now + 4.seconds).to_i do
assert_performed_with at: (Time.now + 6.seconds).to_i do
assert_performed_with at: (Time.now + 8.seconds).to_i do
RetryJob.perform_later "CustomWaitTenAttemptsError", 5
end
end
end
end
end
RetryJob.perform_later "CustomWaitTenAttemptsError", 5, :log_scheduled_at
assert_equal [
"Raised CustomWaitTenAttemptsError for the 1st time",
"Next execution scheduled at #{(Time.now + 2.seconds).to_f}",
"Raised CustomWaitTenAttemptsError for the 2nd time",
"Next execution scheduled at #{(Time.now + 4.seconds).to_f}",
"Raised CustomWaitTenAttemptsError for the 3rd time",
"Next execution scheduled at #{(Time.now + 6.seconds).to_f}",
"Raised CustomWaitTenAttemptsError for the 4th time",
"Next execution scheduled at #{(Time.now + 8.seconds).to_f}",
"Successfully completed job"
], JobBuffer.values
end
test "successfully retry job throwing one of two retryable exceptions" do
perform_enqueued_jobs do
RetryJob.perform_later "SecondRetryableErrorOfTwo", 3
RetryJob.perform_later "SecondRetryableErrorOfTwo", 3
assert_equal [
"Raised SecondRetryableErrorOfTwo for the 1st time",
"Raised SecondRetryableErrorOfTwo for the 2nd time",
"Successfully completed job" ], JobBuffer.values
end
assert_equal [
"Raised SecondRetryableErrorOfTwo for the 1st time",
"Raised SecondRetryableErrorOfTwo for the 2nd time",
"Successfully completed job" ], JobBuffer.values
end
test "discard job throwing one of two discardable exceptions" do
perform_enqueued_jobs do
RetryJob.perform_later "SecondDiscardableErrorOfTwo", 2
assert_equal [ "Raised SecondDiscardableErrorOfTwo for the 1st time" ], JobBuffer.values
end
RetryJob.perform_later "SecondDiscardableErrorOfTwo", 2
assert_equal [ "Raised SecondDiscardableErrorOfTwo for the 1st time" ], JobBuffer.values
end
test "successfully retry job throwing DeserializationError" do
perform_enqueued_jobs do
RetryJob.perform_later Person.new(404), 5
assert_equal ["Raised ActiveJob::DeserializationError for the 5 time"], JobBuffer.values
end
RetryJob.perform_later Person.new(404), 5
assert_equal ["Raised ActiveJob::DeserializationError for the 5 time"], JobBuffer.values
end
private
def adapter_skips_scheduling?(queue_adapter)
[
ActiveJob::QueueAdapters::InlineAdapter,
ActiveJob::QueueAdapters::AsyncAdapter,
ActiveJob::QueueAdapters::SneakersAdapter
].include?(queue_adapter.class)
end
end
......@@ -30,7 +30,13 @@ class RetryJob < ActiveJob::Base
discard_on FirstDiscardableErrorOfTwo, SecondDiscardableErrorOfTwo
discard_on(CustomDiscardableError) { |job, error| JobBuffer.add("Dealt with a job that was discarded in a custom way. Message: #{error.message}") }
def perform(raising, attempts)
before_enqueue do |job|
if job.arguments.include?(:log_scheduled_at) && job.scheduled_at
JobBuffer.add("Next execution scheduled at #{job.scheduled_at}")
end
end
def perform(raising, attempts, *)
raising = raising.shift if raising.is_a?(Array)
if raising && executions < attempts
JobBuffer.add("Raised #{raising} for the #{executions.ordinalize} time")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册