我正在维护一个 Rails 应用程序,我在该应用程序上运行延迟作业 gem 来发送电子邮件。
我刚刚注意到由于应用程序中的错误,我所有延迟的工作在过去几天都失败了。现在该错误已修复,我想尽快处理这些作业,但它们已经有太多失败的尝试,并且工作人员从数据库中拉出它们的延迟很大。
我尝试通过更新delayed_jobs 表并将尝试次数设置为较小的数字并将run_at 属性设置为当前时间,但仍然没有帮助。
你能告诉我如何强迫工人执行它们吗?
我正在维护一个 Rails 应用程序,我在该应用程序上运行延迟作业 gem 来发送电子邮件。
我刚刚注意到由于应用程序中的错误,我所有延迟的工作在过去几天都失败了。现在该错误已修复,我想尽快处理这些作业,但它们已经有太多失败的尝试,并且工作人员从数据库中拉出它们的延迟很大。
我尝试通过更新delayed_jobs 表并将尝试次数设置为较小的数字并将run_at 属性设置为当前时间,但仍然没有帮助。
你能告诉我如何强迫工人执行它们吗?
可以手动启动,试试
Delayed::Job.all.each { |j| j.invoke_job }
或者
Delayed::Job.all.each { |j| j.payload_object.perform }
好的,所以我终于明白了!
诀窍实际上是将 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)>
现有的答案都没有完全正确,所以我在这里添加。
神奇的是让延迟的作业相信这些作业确实没有失败,所以通过 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”或尝试字段都可以阻止作业运行。
现在该错误已修复,我想尽快处理这些作业,但它们已经有太多失败的尝试,并且工作人员从数据库中拉出它们的延迟很大。
这意味着,由于作业没有从表中删除,因此还有更多尝试等待延迟作业。延迟作业的默认行为是在找到可用作业时从队列中读取 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 天之后。