我使用以下设置与Redis代理和后端:
chord([A, A, A, ...])(B)
AbortableTask
作为基础并定期检查task.is_aborted()
标记。用户可以中止A任务。不幸的是,在所有任务A实例上调用AbortableAsyncResult(task_a_id).abort()
时,只有活动的实例被中止。工作人员尚未收到的任务状态更改为ABORTED
,但仍然会处理它们,is_aborted()
标志返回False。
我当然可以revoke()
暂挂任务而不是abort()
- 但问题是,在这种情况下,和弦体(任务B)不再执行了。
如何停止所有待处理和正在运行的任务A实例,同时仍然确保任务B运行?
答案 0 :(得分:2)
只需获取A
所有实例的ID列表并停止播放。
考虑这个简单的和弦
from celery import chord
my_chord = chord(a.si() for i in range(300))(b.si())
现在,您可以使用
从a
实例获取子任务列表(my_chord
任务的所有实例)
for taks in my_chord.parent.subtasks:
print(task.id)
现在,您可以对这些任务实施做任何想做的事情。例如,无论当前状态如何,都可以撤销所有状态。
from celery.task.control import revoke
for task in my_chord.parent.subtasks:
revoke(task.id, terminate=True)
默认情况下, revoke
仅杀死待处理的任务。但是如果你将terminate=True
传递给它,它也会杀死正在执行的任务。
此外,在所有子任务成功执行后,将调用和弦的回调函数。由于您要取消和弦的子任务,因此不会调用回叫功能,并且和弦任务会导致失败。因此,您必须重试回调任务。
答案 1 :(得分:0)
您可能需要考虑使用观看A任务的和弦任务,而不是对任务本身进行整理。我的意思是和弦将包含任务,每隔一段时间检查一次运行任务(A),看看它们是否已完成或被撤销。当所有这些成功地将带有链的和弦返回到任务B
时