我正在使用Celery和Redis作为代理,我可以看到队列实际上是一个redis列表,其中序列化任务作为项目。
我的问题是,如果我在调用<task>.delay()
时有一个AsyncResult对象,有没有办法确定项目在队列中的位置?
更新
我终于可以使用以下方式获得该职位:
from celery.task.control import inspect
i = inspect()
i.reserved()
但它有点慢,因为它需要与所有工人沟通。
答案 0 :(得分:9)
你提到的inspect.reserved()/scheduled()
可能有用,但不行
始终准确,因为它只考虑任务
工人们预先准备好了。
Celery不允许队列上的带外操作,例如删除消息 从队列中,或重新排序它们,因为它不会在分布式系统中扩展。 消息可能尚未到达队列,这可能导致 在竞争条件下并且在实践中它不是具有事务性的顺序队列 操作,但源自多个位置的消息流。 也就是说,Celery API基于严格的消息传递语义。
可以直接在某些代理上访问队列 Celery支持(如Redis或Database),但这不是公共API的一部分, 你不鼓励这样做,但当然如果你没有计划 大规模支持操作,您应该做最方便的事情 并放弃我的建议。
如果这只是为了让用户知道他的工作何时完成,那么 我相信你可以想出一个算法来预测任务何时执行, 如果您只有队列的长度和插入每个任务的时间。
第一个是redis.len("celery")
,后者可以
通过聆听task_sent
信号来添加自己:
from celery.signals import task_sent
@task_sent.connect
def record_insertion_time(id, **kwargs):
redis.zadd("celery.insertion_times", id)
在此处使用排序集:http://redis.io/commands/zadd
对于纯消息传递解决方案,您可以使用专用监视器 消耗Celery事件流并预测任务何时完成。 http://docs.celeryproject.org/en/latest/userguide/monitoring.html#event-reference
(只是注意到任务发送中缺少时间戳字段 文档,但随着该事件发送时间戳,所以我将修复它。)
事件还包含一个“时钟”字段,它是一个逻辑时钟 (见http://en.wikipedia.org/wiki/Lamport_timestamps), 这可以用于检测分布式事件的顺序 系统不依赖于每台机器上的系统时间 同步(这是不可能实现的)。