根据task.revoke()
上的docs:
所有工作节点都保留已撤销任务ID的内存,无论是在内存中还是在磁盘上持久
和
通过向所有工作人员发送广播消息来撤销任务,工作人员会在内存中保留已撤销任务的列表。当工作人员启动时,它会将已撤销的任务与群集中的其他工作人员同步。
听起来这些任务在您撤销之后仍然存在。我不明白为什么没有明确的方法来撤销任务并将其从队列中删除。
文档似乎意味着您需要无限期地保留已撤销任务的列表,以确保新工作人员在某些情况下不会接收它们。
我也知道有一个完全清除任务队列的功能,但这不是我想要的。
有没有办法撤销任务并从Celery的任务队列中清除它(只有它)?
答案 0 :(得分:0)
除了用purge
或用broker
中的手动命令删除所有消息外,不可能仅删除队列中的一封邮件。
但是,您可能不介意由工作人员处理的撤消任务从队列中删除。因此,您不必维护一个永久吊销的ID列表。
仅当工作人员忙于该任务或计划将任务安排在以后时,才应将ID保留在该工作人员尚未处理的列表上。
如果可以同时停止所有工作人员并且您要保留已标记的已撤销任务,则该列表应该是持久的。否则,一名新工人会向已经在运行的工人询问要标记为已撤消的任务。
注意:我分析了一个以Redis为经纪人和后端的案例,以获取答案。最终被撤消的任务从队列中删除,因此可见(标记为已撤消)。
revoke()
,因此会向所有工作人员发送一条消息,以将任务标记为已撤消。该ID在每个工作人员的撤消列表中(请参阅日志Tasks flagged as revoked: A
中的内容)我不知道您不能直接从队列中删除任务的确切原因。但是我的直觉是:
答案 1 :(得分:0)
Celery文档中有一小段漂亮的小节,名为“ revoke: Revoking tasks”,请仔细阅读。
简而言之-默认行为是正常停止任务。此外,任务可能只是在队列中等待,在这种情况下,撤消只是将其从队列中删除(最简单的情况)。更为复杂的是当任务已经在运行时...使用terminate=True
,您告诉Celery worker将SIGINT发送给执行任务的worker进程。但是在某些情况下可能不起作用。 -就像您在Linux中具有“僵尸进程”一样,您可能具有难以撤销的“僵尸任务”(我知道-这不是最好的类比,但是您会明白这一点),在这种情况下,您可以通过以下方式撤销它们SIGKILL(通过terminate=True, signal='SIGKILL'
撤消)。撤消成功后,您将不会在队列中看到该任务。