如何按任务名称检查和取消Celery任务

时间:2013-03-22 16:52:37

标签: python redis celery

我正在使用Celery(3.0.15)与Redis作为经纪人。

是否有一种直接的方法来查询Celery队列中存在的具有给定名称的任务数量?

并且,作为后续,有没有办法取消Celery队列中存在的具有给定名称的所有任务?

我已经通过Monitoring and Management Guide并且没有看到解决方案。

5 个答案:

答案 0 :(得分:30)

# Retrieve tasks
# Reference: http://docs.celeryproject.org/en/latest/reference/celery.events.state.html
query = celery.events.state.tasks_by_type(your_task_name)

# Kill tasks
# Reference: http://docs.celeryproject.org/en/latest/userguide/workers.html#revoking-tasks
for uuid, task in query:
    celery.control.revoke(uuid, terminate=True)

答案 1 :(得分:13)

有一个问题,早期的答案没有解决,如果他们不知道,可能会甩掉他们。

在已发布的解决方案中,我使用Danielle's进行了一次小修改:我将任务导入到我的文件中并使用其.name属性将任务名称传递给{ {1}}。

.tasks_by_type()

但是,此解决方案将忽略那些已安排在未来执行的任务。像一些评论其他答案的人一样,当我检查app.control.revoke( [uuid for uuid, _ in celery.events.state.State().tasks_by_type(task.name)]) 返回时我有一个空列表。事实上我的队列是空的。但我知道有些任务计划在未来执行,这些是我的主要目标。我可以通过执行.tasks_by_type()来查看它们,但它们不受上述代码的影响。

我设法撤消了计划任务:

celery -A [app] inspect scheduled

app.control.revoke( [scheduled["request"]["id"] for scheduled in chain.from_iterable(app.control.inspect().scheduled() .itervalues())]) 返回一个词典,其键是工作人员姓名,值是列表的计划信息(因此,app.control.inspect().scheduled()需要从chain.from_iterable导入)。任务信息位于调度信息的itertools字段中,"request"包含任务ID。请注意,即使在撤销后,计划任务仍将显示在计划任务中。已撤销的计划任务将不会从计划任务列表中删除,直到其计时器到期或Celery执行某些清理操作。 (重新启动工作程序会触发此类清理。)

答案 2 :(得分:4)

您可以在一个请求中执行此操作:

app.control.revoke([
    uuid
    for uuid, _ in
    celery.events.state.State().tasks_by_type(task_name)
])

答案 3 :(得分:2)

和 Celery 一样,这里的任何答案都对我根本不起作用,所以我做了我通常的事情,并编写了一个直接检查 redis 的解决方案。来了……

# First, get a list of tasks from redis:
import redis, json

r = redis.Redis(
    host=settings.REDIS_HOST,
    port=settings.REDIS_PORT,
    db=settings.REDIS_DATABASES['CELERY'],
)
l = r.lrange('celery', 0, -1)

# Now import the task you want so you can get its name
from my_django.tasks import my_task

# Now, import your celery app and iterate over all tasks 
# from redis and nuke the ones that have a matching name.
from my_django.celery_init import app
for task in l:
     task_headers = json.loads(task)['headers']
     task_name = task_headers["task"]
     if task_name == my_task.name:
         task_id = task_headers['id']
         print("Terminating: %s" % task_id)
         app.control.revoke(task_id, terminate=True)

请注意,以这种方式撤消可能不会撤消预取任务,因此您可能不会立即看到结果。

此外,此答案不支持优先任务。如果您想对其进行修改以实现该目的,则需要my other answer that hacks redis 中的一些提示。

答案 4 :(得分:1)

看起来flower提供监控:

https://github.com/mher/flower

  

使用Celery Events进行实时监控

     

任务进度和历史能够显示任务详细信息(参数,   开始时间,运行时等)图形和统计远程控制

     

查看工作人员状态和统计信息关闭并重新启动工作人员   实例控制工作线池大小和自动缩放设置查看和   修改工作者实例当前从View中消耗的队列   正在运行的任务查看计划任务(ETA /倒计时)查看保留和   已撤销的任务应用时间和速率限制配置查看器撤消   或终止任务HTTP API

     

OpenID身份验证