Повторите задание Celery с экспоненциальным откатом - PullRequest
61 голосов
/ 16 марта 2012

Для такой задачи:

from celery.decorators import task

@task()
def add(x, y):
    if not x or not y:
        raise Exception("test error")
    return self.wait_until_server_responds(

если оно выдает исключение, и я хочу повторить его со стороны демона, как можно применить алгоритм экспоненциального отката, т. Е. Через 2^2, 2^3,2^4 и т. Д. Секунд?

Также поддерживается ли повторная попытка со стороны сервера, так что если рабочий окажется убитым, то следующий рабочий, который будет порождаться, будет выполнять задачу повторной попытки?

Ответы [ 2 ]

120 голосов
/ 17 марта 2012

Атрибут task.request.retries содержит количество попыток на данный момент, поэтому вы можете использовать его для реализации экспоненциального отката:

from celery.task import task

@task(bind=True, max_retries=3)
def update_status(self, auth, status):
    try:
        Twitter(auth).update_status(status)
    except Twitter.WhaleFail as exc:
        self.retry(exc=exc, countdown=2 ** self.request.retries)

Для предотвращения ThunderingЗадача «Стадо» , вы можете рассмотреть возможность добавления случайного джиттера к экспоненциальному откату:

import random
self.retry(exc=exc, countdown=int(random.uniform(2, 4) ** self.request.retries))
22 голосов
/ 28 сентября 2017

Начиная с Celery 4.2, вы можете настроить свои задачи на автоматическое использование экспоненциального отката: http://docs.celeryproject.org/en/master/userguide/tasks.html#automatic-retry-for-known-exceptions

@app.task(autoretry_for=(Exception,), retry_backoff=2)
def add(x, y):
    ...

(Это уже было в документации по Celery 4.1, но на самом деле не было выпущено, см. запрос на слияние )

...