如何使活动作业永远重试所有作业?



我不希望活动作业在失败时删除作业。我希望有机会修复故障,然后让它们重新运行。我试着这样做:

class ApplicationJob < ActiveJob::Base
retry_on Exception, attempts: Float::INFINITY
end

,但它没有工作。一个邮件任务失败了,被丢弃了。我使用delayed_job作为实现。

你知道怎么做吗?

如果您使用的是Delayed::Job,那么最终会有两个相互叠加的重试机制。Active Job, Rails通用实现,和Delayed::Job.

For Active::Job you can do:

class ApplicationJob < ActiveJob::Base
retry_on Exception, wait: :exponentially_longer, attempts: Float::INFINITY
end

如果没有wait: :exponentially_longer,您可能会以每3秒尝试大量作业告终。

如果您使用的是Delayed::Job,则此重试方法的行为可能有点奇怪。作业运行并且似乎成功了,但是由于它失败了,ActiveJob创建一个新的作业稍后运行。因此,delay::Job中的字段attempts保持为0,您需要查看字段handler以查看它运行了多少次。

一个ActiveJob最后一次失败,这个异常会出现在Delayed::Job,它有自己的重试机制。延迟:作业默认重试25次,然后删除作业。

要使延迟作业永远保持尝试,您可以创建一个初始化文件config/initializers/delayed_job_config.rb,更改max_attempts的值:

Delayed::Worker.max_attempts = Float::INFINITY

如果您担心丢失作业,可以通过设置:

Delayed::Worker.destroy_failed_jobs = false

您使用哪一个,或者如何混合使用它们取决于您。使用Delayed::Job's使数据库更有意义,使用ActiveJob's意味着该方法可以传输到其他实现。

retry_on exception, attempts::unlimited (Rails 7.0+)

从Rails 7.0开始,ActiveJob支持将attempts: :unlimited传递给retry_on方法的能力:

:attempts-重新排队作业指定的次数(默认:5次)或符号引用:unlimited重试作业,直到成功

例如:

class RemoteServiceJob < ActiveJob::Base
# ...
retry_on CustomInfrastructureException, wait: 5.minutes, attempts: :unlimited
def perform(*args)
# ...
end
end

来源:

  • ActiveJob:例外::类方法# retry_on。
  • retry_on参数尝试现在接受:无限制。
  • Rails的新特性

我们可以通过在retry_on文档

之后将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

应该可以了

retry_on Exception, wait: 5。分钟,尝试数::unlimited

https://edgeapi.rubyonrails.org/classes/ActiveJob/Exceptions/ClassMethods.html

相关内容

  • 没有找到相关文章

最新更新