如何解决如何让 Active Job 永远重试所有作业?
我不希望活跃的工作在失败时放弃工作。我希望有机会修复故障,然后让它们重新运行。我试过这样做:
class ApplicationJob < ActiveJob::Base
retry_on Exception,attempts: Float::INFINITY
end
但是没有用。电子邮件作业失败并被丢弃。我使用 delay_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
来实现自己的重试逻辑
可能有自己的重试机制或将其放入等待队列中进行检查。
如果自定义逻辑的重试尝试失败,您还可以传递一个将被调用的块,而不是让异常冒泡。这个块是以作业实例作为第一个参数,错误实例作为第二个参数产生的。
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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。