Создание 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?