有没有办法从作业任务本身内部确定正在运行的delayed_job作业的状态?我有一个与服务相互作用的工作,这个服务非常不稳定,对于某类连接失败,我想要重新排队,只有在重试限制再次发生连接失败时才会引发异常。
伪代码,用于演示我希望能够做到的事情:
def do_thing
service.send_stuff(args)
rescue Exception1, Exception2
if job.retries == JOBS_MAX
raise
else
job.requeue
end
end
我不想在任何失败时引发异常,因为通常这项工作将在以后的重试中完成,并且它只是为我制造噪音。我做想知道它是否永远不会完成。
答案 0 :(得分:1)
正如您所说,如果延迟作业运行器到达perform
队列的末尾,那么它将被视为成功运行并从队列中删除。所以你必须阻止它走到尽头。没有重新排队 - 即使它是一个具有新属性的新记录。因此,您可以重新考虑导致作业通知您异常的任何内容。例如,您可以添加一个通知您的条件......
潜在解决方案
您可以使用JOBS_MAX
获取默认的Delayed::Worker.max_attempts
(使用伪编码),也可以通过定义方法来设置自己的每个作业,例如:max_attempts
。
# Fail permanently after the 10th failure for this job
def max_attempts
10
end
也就是说,此方法可用于以下内容:
您还可以使用callback hooks。如果已定义,则延迟作业将通过error
方法回调到您的有效内容对象。因此,您可以使用error
方法通知您超出给定尝试次数的实际异常。要做到这一点......
在回调中,Delayed :: Job对象本身作为第一个参数返回:
def error(job, exception)
job.attempts # gives you the current attempt number
# If job.attempts is greater than max_attempts then send exception notification
# or whatever you want here...
end
因此,您可以使用回调开始添加逻辑,以便何时通知您自己以及何时不通知。我甚至可能建议制作一组基本功能,您可以将其包含在所有有效负载对象中以执行这些操作......但这取决于您和您的设计。
答案 1 :(得分:1)
为DJ定义自定义作业,为max_attempts
设置一个数字,并为error
回调设置行为。这是未经测试的,但它可能看起来像这样:
class DoThingJob
def max_attempts; @max_attempts ||= 5; end
def error(job, exception)
case exception
when Exception1, Exception2
# will be requeued automatically until max_attempts is reached
# can add extra log message here if desired
else
@max_attempts = job.attempts
# this will cause DJ to fail the job and not try again
end
end
end
注意强>
我在@pdobb发布他的答案之前开始写这篇文章。无论如何我都会发布它,因为它提供了一些关于如何处理异常和重新排队逻辑的更多细节。