Створення 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?