Создание AsyncResult
объекта из идентификатора задачи - это способ, рекомендованный в FAQ для получения статуса задачи, когда единственное, что у вас есть, - это идентификатор задачи.
Однако, начиная с Celery 3.x, есть серьезные предостережения, которые могут укусить людей, если они не обратят на них внимание. Это действительно зависит от конкретного сценария использования.
По умолчанию Celery не записывает «запущенное» состояние.
Чтобы Celery записал, что задача выполняется, необходимо установить task_track_started
значение True
. Вот простая задача, которая проверяет это:
@app.task(bind=True)
def test(self):
print self.AsyncResult(self.request.id).state
Когда task_track_started
есть False
(значение по умолчанию), состояние отображается, PENDING
даже если задача запущена. Если вы установите task_track_started
на True
, то состояние будет STARTED
.
Состояние PENDING
означает «я не знаю».
С AsyncResult
состоянием PENDING
не означает ничего, кроме того, что Celery не знает статус задачи. Это могло быть по любому количеству причин.
Во-первых, AsyncResult
могут быть созданы с недопустимыми идентификаторами задач. Такие «задачи» будут считаться отложенными для Celery:
>>> task.AsyncResult("invalid").status
'PENDING'
Итак, никто не будет скармливать явно недействительные идентификаторы AsyncResult
. Достаточно справедливо, но он также имеет эффект, AsyncResult
который также учитывает задачу, которая успешно выполнена, но о которой Celery забыл PENDING
. Опять же, в некоторых сценариях использования это может быть проблемой. Частично проблема зависит от того, как Celery настроен для хранения результатов задач, потому что это зависит от доступности «надгробий» в серверной части результатов. («Надгробия» - это термин, который используется в документации по сельдерею для фрагментов данных, которые фиксируют, как закончилась задача.) Использование AsyncResult
вообще не будет работать, если оно task_ignore_result
есть True
. Более неприятная проблема заключается в том, что Celery по умолчанию истекает срок действия надгробий. Вresult_expires
настройка по умолчанию установлена на 24 часа. Итак, если вы запускаете задачу и записываете идентификатор в долгосрочное хранилище, и более 24 часов спустя вы создаете AsyncResult
с ним задачу, статус будет PENDING
.
Все «настоящие задачи» запускаются в PENDING
штате. Таким образом, PENDING
выполнение задачи может означать, что задача была запрошена, но никогда не продвинулась дальше (по какой-либо причине). Или это может означать, что задача выполнена, но Celery забыл о своем состоянии.
Ой! AsyncResult
у меня не сработает. Что еще я могу сделать?
Я предпочитаю отслеживать цели, а не сами задачи . Я храню некоторую информацию о задачах, но это второстепенно по отношению к отслеживанию целей. Цели хранятся в хранилище независимо от сельдерея. Когда запрос должен выполнить вычисление, зависит от достигнутой цели, он проверяет, была ли цель уже достигнута, если да, то он использует эту кешированную цель, в противном случае запускает задачу, которая повлияет на цель, и отправляет ее в клиент, сделавший HTTP-запрос, является ответом, который указывает, что он должен дождаться результата.
Имена переменных и гиперссылки выше предназначены для Celery 4.x. В 3.x соответствующие переменные и гиперссылки: CELERY_TRACK_STARTED
, CELERY_IGNORE_RESULT
, CELERY_TASK_RESULT_EXPIRES
.
x
?