我有一个自我调用的芹菜任务(使用do_stuff.apply_async(queue="foo")
)。以前我已经运行过app.control.add_consumer("foo", reply=True)
,所以我的工人可以从此队列中消费。
一段时间后,我想停止该队列中的所有任务以及从do_stuff
启动的所有正在运行的任务。
所以我运行这段代码:
app.control.cancel_consumer("foo", reply=True)
i = app.control.inspect()
for queue in [i.active, i.scheduled, i.reserved]:
for worker_name, worker_tasks in queue().items():
for task in worker_tasks:
args = ast.literal_eval(task["args"])
if "do_stuff" in task["name"] and args[0] == crawler.name:
app.control.revoke(task["id"], terminate=True)
这种“有效”的方式。它确实从do_stuff
停止了所有正在运行的任务,并且确实清除了计划的任务(或者,至少在运行此代码后,我在Flower中看不到任何任务)。
问题在于,如果我再次运行app.control.add_consumer("foo", reply=True)
,而不运行其他任何东西,则新任务开始运行。这意味着celery / redis以某种方式设法将任务保留在某处。
为什么会这样?这些“隐藏”任务保存在哪里?以及如何删除它们?
答案 0 :(得分:1)
回答我自己的问题:发生这种情况的原因是,当我不让工作人员从队列中消费(通过调用cancel_consumer
)时,队列本身仍然包含所有内容。
我找到了一种(以编程方式)刷新队列的方法:
from celery.bin.celery import CeleryCommand
cmd = CeleryCommand()
super(CeleryCommand, cmd).execute_from_commandline([
'',
'purge',
'-f',
'-Q', queue_name,
'-A', 'main'
])