我正在运行 Rails 5.1、ruby 2.5、Sidekiq。 我设置了一个简单的用例:
class RetryJobException < Exception
end
class CustomJob < ActiveJob::Base
retry_on RetryJobException, wait: 3.seconds, attempts: 2 do
puts "RETRYING"
end
def perform(*args)
raise RetryJobException
end
end
这里发生的情况是,当我运行此作业并引发
RetryJobException
时,CustomJob
在 30 秒(而不是 3...)后重新运行无限次(而不是 2),直到我杀死 Sidekiq 的进程。 “RETRYING”永远不会在任何地方打印,这表明 retry_on
块中的代码永远不会被执行。
根据文档,这应该是一个基本用例,但是,我遇到了这些问题。我做错了什么?
这对我有用:
class RetryJobException < Exception
end
class UnprocessableJob < StandardError; end
class CustomJob < ActiveJob::Base
retry_on RetryJobException, wait: 3.seconds, attempts: 2 do
puts "RETRYING"
before_perform { raise UnprocessableJob }
end
discard_on UnprocessableJob
def perform(*args)
raise RetryJobException
end
end
我遇到了同样的问题,但仔细阅读文档后,我发现了这一点:
您还可以传递一个块,如果自定义逻辑的重试尝试失败,将调用该块,而不是让异常冒泡。该块是使用作业实例作为第一个参数和错误实例作为第二个参数生成的。
我的场景是在作业失败时通知我,然后我决定改用rescue_form:
module LoggableJob
extend ActiveSupport::Concern
included do
rescue_from(StandardError) do |exception|
ExceptionNotifier.notify_exception(exception, data: job_exception_data)
AppLog.exception(exception, self, data: job_exception_data)
# https://apidock.com/rails/v5.0.0.1/ActiveJob/Enqueuing/retry_job
retry_job wait: 5.minutes, priority: 5
end
end
def job_exception_data
{ queue_name: queue_name, args: arguments, job_id: job_id}
end
end