芹菜工作者在调用retry()后不重试任务

时间:2012-08-10 13:35:02

标签: python celery

我有一个任务:

    @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循环,所以我的任务永远不会重试。

2 个答案:

答案 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)