12

我有一个任务:

    @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 代理并启用了 mongodb 结果后端。

当调用任务的 retry() 方法时,无论是从条件语句还是在捕获异常之后,都不会重试该任务。

在工人的终端我收到这样的消息:

[2012-08-10 19:21:54,909: INFO/MainProcess] 任务 request_task[badb3131-8964-41b5-90a7-245a8131e68d] 重试:可以重试任务

有什么问题?

更新:最后,我没有解决这个问题,不得不在任务中使用 while 循环,所以我的任务永远不会重试。

4

2 回答 2

6

我知道这个答案为时已晚,但是您看到的日志消息意味着您直接调用任务request_task()而不是排队,因此它不在工作人员上运行,因此如果有任何异常,这样做会引发异常,或者一个Retry例外,如果您想查看,这是该方法的代码:Task.retry

# 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))

Usingtask.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)
于 2019-08-19T15:07:16.180 回答
1

您应该阅读 Celery 文档中有关重试的部分。 http://celery.readthedocs.org/en/latest/userguide/tasks.html#retrying

看起来为了重试,您必须引发重试异常。

raise request_task.retry()

这似乎使重试由装饰您的任务的函数处理。

于 2014-07-02T22:17:36.323 回答