我正在维护一个rails应用程序,我正在运行delayed_job gem来发送电子邮件。
我刚注意到,由于应用程序中存在错误,我所有延迟的工作在过去几天都失败了。现在修复了这个bug,我想尽快处理这些作业,但是他们已经有太多失败的尝试,并且工作人员将他们从数据库中拉出来并且有很大的延迟。
我尝试过更新delayed_jobs表并将尝试次数设置为较小的数字,将run_at属性设置为当前时间,但仍无法提供帮助。
你能告诉我如何强迫工人执行它们?
答案 0 :(得分:10)
您可以手动启动它,尝试
Delayed::Job.all.each { |j| j.invoke_job }
或
Delayed::Job.all.each { |j| j.payload_object.perform }
答案 1 :(得分:3)
好的,最后我明白了!
诀窍是将run_at属性更新为当前时间,但是应用程序的当前时间 - 这是数据库后面3小时。
当我将其设置为现在() - 间隔'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)>
答案 2 :(得分:2)
现有的答案都没有完全正确,所以我在这里添加。
神奇的是说服延迟的工作,这些工作确实没有失败,所以通过rails db console:
-> 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”或尝试字段可以使作业无法运行。
答案 3 :(得分: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天之后。