如何让 Active Job 永远重试所有作业?
How do I make Active Job retry all jobs forever?
我不希望活动作业在失败时丢弃作业。我想有机会修复故障然后让他们重新运行。我试过这样做:
class ApplicationJob < ActiveJob::Base
retry_on Exception, attempts: Float::INFINITY
end
但是没用。电子邮件作业失败并被丢弃。我正在使用 delayed_job 作为实现。
有什么办法吗?
如果您使用的是 Delayed::Job,您最终会得到两个重试机制。 Active Job,Rails 通用实现,以及 Delayed::Job.
对于 Active::Job 你可以这样做:
class ApplicationJob < ActiveJob::Base
retry_on Exception, wait: :exponentially_longer, attempts: Float::INFINITY
end
如果没有 wait: :exponentially_longer
,您可能会每 3 秒尝试大量作业。
如果您使用 Delayed::Job,此重试方法的行为可能会有点奇怪。作业 运行 似乎成功了,但由于它失败了,ActiveJob 稍后会为 运行 创建一个新作业。因此,Delayed::Job 中的字段 attempts
保持为 0,您需要查看字段 handler
以查看它是 运行.
的次数
一个 ActiveJob 最后一次失败,异常冒泡到 Delayed::Job 它有自己的重试机制。 Delayed::Job 默认 retries 25 times and then deletes the job.
要让延迟作业一直尝试下去,您可以创建一个初始化文件 config/initializers/delayed_job_config.rb
更改 max_attempts
值:
Delayed::Worker.max_attempts = Float::INFINITY
如果您担心失去工作,工作可以失败并且不会通过设置被删除:
Delayed::Worker.destroy_failed_jobs = false
您使用两者中的哪一个,或者如何混合它们取决于您。使用 Delayed::Job 使数据库更有意义,使用 ActiveJob 意味着该方法可以传输到其他实现。
我们可以通过在 retry_on Documentation
之后将 block
传递给 retry_on
来实现自己的重试逻辑
may have its own retry mechanism or place it in a holding queue for inspection.
You can also pass a block that'll be invoked if the retry attempts fail for custom logic rather than letting the exception bubble up. This block is yielded with the job instance as the first and the error instance as the second parameter.
retry_on Exception do |job, error|
MyJob.perform_later(job)
end
无限重试的工作示例:
# test_job.rb
require 'active_record'
require 'active_support'
require 'active_job'
require 'globalid'
ActiveJob::Base.queue_adapter = :async
GlobalID.app = 'app'
logger = ActiveJob::Base.logger
class ProcessPhotoJob < ActiveJob::Base
retry_on ActiveRecord::RecordNotFound do |job, error|
logger.info " retrying job #{job}"
ProcessPhotoJob.perform_later(job)
end
def perform
logger.info ' performing, but getting error:'
raise ActiveRecord::RecordNotFound
end
end
ProcessPhotoJob.perform_later
while true
sleep 1
end
可以 运行 与:
ruby test_job.rb
这应该有效
retry_on 异常,等待:5.minutes,尝试::无限制
https://edgeapi.rubyonrails.org/classes/ActiveJob/Exceptions/ClassMethods.html
我不希望活动作业在失败时丢弃作业。我想有机会修复故障然后让他们重新运行。我试过这样做:
class ApplicationJob < ActiveJob::Base
retry_on Exception, attempts: Float::INFINITY
end
但是没用。电子邮件作业失败并被丢弃。我正在使用 delayed_job 作为实现。
有什么办法吗?
如果您使用的是 Delayed::Job,您最终会得到两个重试机制。 Active Job,Rails 通用实现,以及 Delayed::Job.
对于 Active::Job 你可以这样做:
class ApplicationJob < ActiveJob::Base
retry_on Exception, wait: :exponentially_longer, attempts: Float::INFINITY
end
如果没有 wait: :exponentially_longer
,您可能会每 3 秒尝试大量作业。
如果您使用 Delayed::Job,此重试方法的行为可能会有点奇怪。作业 运行 似乎成功了,但由于它失败了,ActiveJob 稍后会为 运行 创建一个新作业。因此,Delayed::Job 中的字段 attempts
保持为 0,您需要查看字段 handler
以查看它是 运行.
一个 ActiveJob 最后一次失败,异常冒泡到 Delayed::Job 它有自己的重试机制。 Delayed::Job 默认 retries 25 times and then deletes the job.
要让延迟作业一直尝试下去,您可以创建一个初始化文件 config/initializers/delayed_job_config.rb
更改 max_attempts
值:
Delayed::Worker.max_attempts = Float::INFINITY
如果您担心失去工作,工作可以失败并且不会通过设置被删除:
Delayed::Worker.destroy_failed_jobs = false
您使用两者中的哪一个,或者如何混合它们取决于您。使用 Delayed::Job 使数据库更有意义,使用 ActiveJob 意味着该方法可以传输到其他实现。
我们可以通过在 retry_on Documentation
之后将block
传递给 retry_on
来实现自己的重试逻辑
may have its own retry mechanism or place it in a holding queue for inspection.
You can also pass a block that'll be invoked if the retry attempts fail for custom logic rather than letting the exception bubble up. This block is yielded with the job instance as the first and the error instance as the second parameter.
retry_on Exception do |job, error|
MyJob.perform_later(job)
end
无限重试的工作示例:
# test_job.rb
require 'active_record'
require 'active_support'
require 'active_job'
require 'globalid'
ActiveJob::Base.queue_adapter = :async
GlobalID.app = 'app'
logger = ActiveJob::Base.logger
class ProcessPhotoJob < ActiveJob::Base
retry_on ActiveRecord::RecordNotFound do |job, error|
logger.info " retrying job #{job}"
ProcessPhotoJob.perform_later(job)
end
def perform
logger.info ' performing, but getting error:'
raise ActiveRecord::RecordNotFound
end
end
ProcessPhotoJob.perform_later
while true
sleep 1
end
可以 运行 与:
ruby test_job.rb
这应该有效
retry_on 异常,等待:5.minutes,尝试::无限制
https://edgeapi.rubyonrails.org/classes/ActiveJob/Exceptions/ClassMethods.html