3

我正在维护一个 Rails 应用程序,我在该应用程序上运行延迟作业 gem 来发送电子邮件。

我刚刚注意到由于应用程序中的错误,我所有延迟的工作在过去几天都失败了。现在该错误已修复,我想尽快处理这些作业,但它们已经有太多失败的尝试,并且工作人员从数据库中拉出它们的延迟很大。

我尝试通过更新delayed_jobs 表并将尝试次数设置为较小的数字并将run_at 属性设置为当前时间,但仍然没有帮助。

你能告诉我如何强迫工人执行它们吗?

4

4 回答 4

10

可以手动启动,试试

Delayed::Job.all.each { |j| j.invoke_job }

或者

Delayed::Job.all.each { |j| j.payload_object.perform }
于 2012-07-19T09:40:55.797 回答
3

好的,所以我终于明白了!

诀窍实际上是将 run_at 属性更新为当前时间,但应用程序的当前时间 - 比数据库晚 3 小时。

当我将其设置为 now() - 间隔“3 小时”时,所有作业都已处理。

编辑:

@rodzyn,我已经尝试过您的建议,但仍然无法正常工作:

[20] pry(main)> Delayed::Job.all.size
  Delayed::Backend::ActiveRecord::Job Load (0.6ms)  SELECT "delayed_jobs".* FROM "delayed_jobs" 
=> 1
[21] pry(main)> Delayed::Job.first.invoke_job
  Delayed::Backend::ActiveRecord::Job Load (0.5ms)  SELECT "delayed_jobs".* FROM "delayed_jobs" LIMIT 1
  Order Load (0.4ms)  SELECT "orders".* FROM "orders" WHERE "orders"."id" = $1 LIMIT 1  [["id", "328"]]
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
=> nil
[22] pry(main)> Delayed::Job.all.size
  Delayed::Backend::ActiveRecord::Job Load (0.6ms)  SELECT "delayed_jobs".* FROM "delayed_jobs" 
=> 1
[23] pry(main)> 
于 2012-07-19T10:07:01.093 回答
3

现有的答案都没有完全正确,所以我在这里添加。

神奇的是让延迟的作业相信这些作业确实没有失败,所以通过 rails db 控制台:

-> rails db
development# update delayed_jobs set run_at = now() - interval '3 hours', attempts = 0, failed_at = null;
UPDATE 30
development# \q

-> rake jobs:workoff  # a good one to use, because it will return immediately if no jobs are found

“failed_at”或尝试字段都可以阻止作业运行。

于 2013-11-12T17:30:40.247 回答
1

现在该错误已修复,我想尽快处理这些作业,但它们已经有太多失败的尝试,并且工作人员从数据库中拉出它们的延迟很大。

这意味着,由于作业没有从表中删除,因此还有更多尝试等待延迟作业。延迟作业的默认行为是在找到可用作业时从队列中读取 5 个作业。没有太多代码更改的一种方法是在延迟配置中进行设置,该设置将从队列中获取更多作业并执行。您可以通过设置来配置它Delayed::Worker.read_ahead

# config/initializers/delayed_job_config.rb
Delayed::Worker.destroy_failed_jobs = false
Delayed::Worker.read_ahead = 10

Delayed::Worker.destroy_failed_jobs避免在最大尝试后删除作业,这也是一个可配置的项目。

延迟作业每 5 秒检查一次数据库中的可用作业,它会在 5 + N ** 4 秒后尝试特定作业。所以,假设一个特定的工作已经失败了 24 次,那么轮到它在 331781 秒后到达,也就是说,如果我没记错的话,大约在 3 天之后。

于 2012-07-19T09:45:38.333 回答