4

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

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

  • 任务 A 进行一些检查。它AbortableTask用作基础并定期检查task.is_aborted()标志。
  • 任务 B 通知用户计算结果

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

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

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

4

2 回答 2

4

只需获取所有实例的 id 列表A并停止它们。

考虑这个简单的和弦

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给它,它也会杀死正在执行的任务。

此外,chord 的回调函数会在其所有子任务执行成功后被调用。由于取消了chord的子任务,所以不会调用回调函数,chord任务会导致失败。因此,您必须重试回调任务。

于 2014-10-22T19:34:40.087 回答
0

您可能需要考虑让和弦任务观看 A 任务,而不是对任务本身进行和弦处理。我的意思是,和弦将包含经常检查正在运行的任务(A)以查看它们是否已完成或撤销的任务。当所有这些都成功返回和弦时,然后链接到任务 B

于 2014-10-22T17:08:55.573 回答