Отменить задачу из сельдерея

Я хочу явно отменить задачу из сельдерея. Вот как я сейчас это делаю: -

from celery.task.control import revoke

revoke(task_id, terminate=True)

где task_id string (также попытался преобразовать его в UUID uuid.UUID(task_id).hex).

После описанной выше процедуры, когда я снова запускаю сельдерей celery worker -A proj, он все еще потребляет одно и то же сообщение и начинает его обрабатывать. Почему?

При просмотре через flower сообщение все еще присутствует в разделе брокера. как мне удалить сообщение, чтобы оно не могло быть снова использовано?

Ответ 1

Как работает revoke?

При вызове метода revoke задача немедленно не удаляется из очереди, все, что она делает, сообщает сельдерею (а не вашему броку!), чтобы сохранить task_id во встроенной памяти set (посмотрите здесь, если вам нравится читать исходный код, как я).

Когда задача попадает в верхнюю часть очереди, Celery проверяет, находится ли она в отброшенном наборе, если это произойдет, она не выполнит ее.

Он работает таким образом, чтобы предотвратить поиск O (n) для каждого вызова revoke, где проверка того, что task_id находится в наборе в памяти, - это просто O (1)

Почему после перезапуска сельдерея ваши отмененные задачи выполняются?

Понимая, как все работает, вы теперь знаете, что set - это просто обычный набор python, который сохраняется в памяти - это означает, что при перезагрузке вы теряете этот набор, но задача (конечно) настойчивость, и когда придет задача, она будет выполнена как обычно.

Что вы можете сделать?

Вам нужно будет установить настойчивость, это делается с помощью начального вашего работника следующим образом:

celery worker -A proj --statedb=/var/run/celery/worker.state

Это сохранит набор в файловой системе.

Литература: