芹菜:在和弦中中止或撤销所有任务

时间:2014-10-22 16:24:50

标签: python task celery chord

我使用以下设置与Redis代理和后端:

chord([A, A, A, ...])(B)

  • 任务A进行一些检查。它使用AbortableTask作为基础并定期检查task.is_aborted()标记。
  • 任务B通知用户有关计算结果的信息

用户可以中止A任务。不幸的是,在所有任务A实例上调用AbortableAsyncResult(task_a_id).abort()时,只有活动的实例被中止。工作人员尚未收到的任务状态更改为ABORTED,但仍然会处理它们,is_aborted()标志返回False。

我当然可以revoke()暂挂任务而不是abort() - 但问题是,在这种情况下,和弦体(任务B)不再执行了。

如何停止所有待处理和正在运行的任务A实例,同时仍然确保任务B运行?

2 个答案:

答案 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