Скасувати вже виконуване завдання з Celery?


96

Я читав документ і шукав, але, здається, не знайшов прямої відповіді:

Чи можете ви скасувати вже виконуване завдання? (як у запущеному завданні, це займає деякий час, і половину шляху потрібно скасувати)

Я знайшов це в документі в розділі поширених запитань про Celery

>>> result = add.apply_async(args=[2, 2], countdown=120)
>>> result.revoke()

Але мені незрозуміло, чи це скасує завдання, що стоять у черзі, чи це призведе до вбивства запущеного процесу на робочому. Дякуємо за будь-яке світло, яке ви можете пролити!

Відповіді:


185

отзыв скасовує виконання завдання. Якщо завдання скасовано, працівники ігнорують завдання і не виконують його. Якщо ви не використовуєте постійне відкликання, ваше завдання може бути виконане після перезапуску працівника.

http://docs.celeryproject.org/en/latest/userguide/workers.html#worker-persistent-revokes

revoke має варіант завершення, який за замовчуванням має значення False . Якщо вам потрібно вбити виконуюче завдання, вам потрібно встановити термінал на True .

>>> from celery.task.control import revoke
>>> revoke(task_id, terminate=True)

http://docs.celeryproject.org/en/latest/userguide/workers.html#revoke-revoking-tasks


3
Це саме те пояснення, яке я шукав, дякую!
dcoffey3296

1
Це працює в розподіленому середовищі? Я маю на увазі, якщо у мене є працівники на декількох машинах, які виконують завдання. Чи відстежує селера, на якій машині виконується завдання?
ksrini

1
Це робить. Спілкування з працівниками відбувається через посередника.
mher

5
result.revoke (terminate = True) повинен робити те саме, що і revoke (task_id, terminate = True)
CamHart

10
Крім того, використання опції термінації є "крайнім засобом для адміністраторів", згідно з останніми документами Celery. Ви ризикуєте завершити ще одне завдання, яке нещодавно розпочато для цього працівника.
kouk


25

Відповідь @ 0x00mh є правильною, однак нещодавні документи про селеру говорять, що використання terminateопції - це " остання інстанція для адміністраторів ", оскільки ви можете випадково припинити інше завдання, яке тим часом почали виконувати. Можливо, кращим рішенням є поєднання terminate=Trueз signal='SIGUSR1'(що призводить до того, що у завданні виникає виняток SoftTimeLimitExceeded).


2
Це рішення дуже добре працювало для мене. Коли SoftTimeLimitExceededпіднімається в моєму завданні, викликається моя спеціальна логіка очищення (реалізована через try/ except/ finally). На мій погляд, це набагато краще, ніж те, що AbortableTaskпропонує ( docs.celeryproject.org/en/latest/reference/… ). З останньою вам потрібна серверна база даних бази даних, і вам доведеться вручну та неодноразово перевіряти стан поточного завдання, щоб перевірити, чи воно було припинено.
Девід Шнайдер

2
Як це краще, наскільки я розумію, якщо є якесь інше завдання, підхоплене процесом, його все одно буде зупинено, буде лише інший виняток.
марксин

Якщо я використовую, worker_prefetch_multiplier = 1оскільки я маю лише кілька тривалих завдань, термінація повинна бути нормальною - оскільки ніякі інші завдання не будуть виконані в результаті завершення - чи я зрозумів це правильно? @spicyramen
maffe

1

Перегляньте такі варіанти завдань: time_limit , soft_time_limit (або ви можете встановити його для робітників). Якщо ви хочете , щоб контролювати не тільки час виконання, то см закінчується аргумент apply_async методу.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.