首页 > 解决方案 > 如何让活动作业永远重试所有作业?

问题描述

我不希望活跃的工作在失败时放弃工作。我希望有机会修复故障,然后让它们重新运行。我试过这样做:

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

但它没有用。电子邮件作业失败并被丢弃。我使用delayed_job 作为实现。

任何想法如何做到这一点?

标签: ruby-on-railsruby-on-rails-6rails-activejob

解决方案


如果你使用 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 创建一个新的以在以后运行。因此,attemptsDelayed::Job 中的字段保持为 0,您需要查看该字段handler以查看它运行了多少次。

一个 ActiveJob 最后一次失败,异常冒泡到 Delayed::Job ,它有自己的重试机制。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 使数据库更有意义,使用ActiveJob 意味着该方法可以传输到其他实现。


推荐阅读