我有一个任务:
@celery.task(name='request_task',default_retry_delay=2,acks_late=True)
def request_task(data):
try:
if some_condition:
request_task.retry()
except Exception as e:
request_task.retry()
我使用celery与mongodb broker和mongodb结果后端启用。
当调用task的retry()方法时,无论是从条件语句还是在捕获异常之后,都不会重试该任务。
在工作者的终端,我得到这样的信息:
[2012-08-10 19:21:54,909:INFO / MainProcess]任务request_task [badb3131-8964-41b5-90a7-245a8131e68d]重试:可以重试任务
有什么不对?
UPDATE:最后,我没有解决这个问题,不得不在任务中使用while循环,所以我的任务永远不会重试。
答案 0 :(得分:1)
您应该阅读Celery文档中有关重试的部分。 http://celery.readthedocs.org/en/latest/userguide/tasks.html#retrying
看起来为了重试,你必须提出重试异常。
raise request_task.retry()
这似乎使重试由装饰任务的函数处理。
答案 1 :(得分:1)
我知道这个答案为时已晚,但是您看到的日志消息意味着您正在直接调用任务request_task()
而不对其进行排队,因此该任务无法在工作程序上运行,因此这样做会增加如果存在异常,则为Retry
异常,如果要查看,则为Task.retry
方法中的code,
# Not in worker or emulated by (apply/always_eager),
# so just raise the original exception.
if request.called_directly:
# raises orig stack if PyErr_Occurred,
# and augments with exc' if that argument is defined.
raise_with_context(exc or Retry('Task can be retried', None))
使用task.retry()
不会在同一工作线程上重试该任务,它会使用task.apply_async()
发送新消息,因此可能会使用其他工作线程重试该消息,这是处理重试时应考虑的事项,您可以使用task.request.retries
访问重试次数,也可以在任务装饰器上设置max_retries
选项。
通过在任务装饰器上使用bind=True
,使任务实例可用作第一个参数:
@app.task(bind=True, name='request_task', max_retries=3)
def request_task(self, data):
# Task retries count
self.request.retries
try:
# Your code here
except SomeException as exc:
# Retry the task
# Passing the exc argument will make the task fail
# with this exception instead of MaxRetriesExceededError on max retries
self.retry(exc=exc)