Створення AsyncResult
об’єкта з ідентифікатора завдання - це спосіб, рекомендований у FAQ, для отримання статусу завдання, коли єдиним, що у вас є, є ідентифікатор завдання.
Однак станом на Селера 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
не означає нічого більше, ніж те, що Селера не знає статусу завдання. Це може бути з будь-якої кількості причин.
З одного боку, їх AsyncResult
можна створити з недійсними ідентифікаторами завдань. Такі "завдання" будуть визнані на розгляді Селері:
>>> task.AsyncResult("invalid").status
'PENDING'
Гаразд, значить, ніхто не збирається подавати очевидно недійсні ідентифікатори AsyncResult
. Досить справедливо, але це також має ефект, який AsyncResult
також розглядатиме завдання, яке успішно виконано, але про яке Селера забув як таке PENDING
. Знову ж таки, у деяких сценаріях використання це може бути проблемою. Частина проблеми залежить від того, як Celery налаштовано на збереження результатів завдань, оскільки це залежить від наявності "надгробків" у сервісі результатів. ("Надгробки" - це термін використання в документації Celery для фрагментів даних, які фіксують, як закінчилося завдання.) Використання AsyncResult
взагалі не буде працювати, якщо task_ignore_result
є True
. Більш неприємна проблема полягає в тому, що Селера за замовчуванням закінчує термін дії надгробків. 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
.
x
?