Создание объекта 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
может быть создан с неверными идентификаторами задач. Такие "задачи" будут считаться ожидающими выполнения сельдереем:
>>> task.AsyncResult("invalid").status
'PENDING'
Хорошо, так что никто не собирается вводить очевидно недействительных идентификаторов на AsyncResult
. Справедливо, но это также имеет эффект, что AsyncResult
также будет считать задачу, которая была успешно запущена, но что Celery забыл быть PENDING
. Опять, в некоторых сценариях использования это может быть проблемой. Часть проблемы зависит от того, как настроен Celery для сохранения результатов задач, потому что это зависит от наличия «надгробий» в бэкенде результатов. («Надгробия» - это термин, используемый в документации Celery для блоков данных, в которых записывается, как завершилось задание.) Использование AsyncResult
не будет работать вообще, если task_ignore_result
равно True
. Еще более неприятная проблема заключается в том, что Celery по умолчанию выбрасывает надгробия. Настройка result_expires
по умолчанию установлена на 24 часа. Поэтому, если вы запускаете задачу и записываете идентификатор в долгосрочное хранилище, и еще через 24 часа, вы создаете с ним AsyncResult
, статус будет PENDING
.
Все "реальные задачи" запускаются в состоянии PENDING
. Таким образом, получение PENDING
для задания может означать, что задание было запрошено, но никогда не продвигалось дальше, чем это (по любой причине). Или это может означать, что задание выполнено, но Сельдери забыл свое состояние.
Ой! AsyncResult
не будет работать для меня. Что еще я могу сделать?
Я предпочитаю отслеживать голов , чем отслеживать самих задач . Я храню некоторую информацию о задачах, но она действительно вторична для отслеживания целей. Цели хранятся в хранилище независимо от сельдерея. Когда запрос должен выполнить вычисление, зависит от того, какая цель была достигнута, он проверяет, была ли цель уже достигнута, если да, то он использует эту кэшированную цель, в противном случае он запускает задачу, которая повлияет на цель, и отправляет клиент, который сделал HTTP-запрос ответом, который указывает, что он должен ждать результата.
Приведенные выше имена переменных и гиперссылки относятся к Celery 4.x. В 3.x соответствующие переменные и гиперссылки: CELERY_TRACK_STARTED
, CELERY_IGNORE_RESULT
, CELERY_TASK_RESULT_EXPIRES
.