Есть ли способ ненасильственно остановить конкретную задачу работника сельдерея?

Как указано в документе Celery , уже выполняющая задача не будет прервана вызовом .revoke(), если не установлен terminate=True. Но это не рекомендуется, потому что он убьет самого работника, который, возможно, уже запустил другую задачу. Означает ли это, что нет надежного, стабильного способа сделать это?

EDIT: celery.contrib.abortable мне не подходит, потому что, как говорится в документации, он работает только с базами данных.

Ответ 1

Запускаемая задача - это выполняемый подпроцесс работника (при использовании prefork), это означает, что единственный способ прервать задачу - убить подпроцесс, который ее запускает.

Вы можете попытаться поэкспериментировать свою собственную обработку обработки отзыва, пытаясь выяснить идентификатор подпроцесса и убить только тот, но, честно говоря, не знаете, стоит ли и действительно ли он может работать.

Я думаю, что короткий ответ - вы не можете.

Во всяком случае, иногда нужно убивать рабочего, особенно на начальных этапах проектов, где вам по-прежнему необходимо правильно оценивать ресурсы, просто убедитесь, что вы где-то записываете выполняемые задачи, чтобы вы могли их перенести или просто использовать CELERY_ACKS_LATE

Ответ 2

Вы можете отправить сигнал HUP вместо TERM, который изящно перезапускает дочерний процесс, не убивая рабочего.

In [80]: import signal

In [81]: x = add.delay(1, 2)

In [82]: x.revoke(terminate=True, signal=signal.SIGHUP)