Повторить задания Сельдерея с экспоненциальным отступлением
Для такой задачи:
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
и т.д. секунд?
Также выполняется повторная попытка с сервера, так что, если рабочий окажется убитым, тогда следующий рабочий, который появляется, выполнит задачу повтора?
Ответы
Ответ 1
Атрибут 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 Herd, вы можете подумать о добавлении случайного дрожания к экспоненциальному отклонению:
import random
self.retry(exc=exc, countdown=int(random.uniform(2, 4) ** self.request.retries))
Ответ 2
Как и в случае с 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):
...
Не обманывайте себя "Новое в версии 4.1". объявление в документах, оно еще не выпущено, см. запрос слияния