通过链ID从异步python芹菜链获得进展

时间:2013-04-30 18:00:58

标签: python celery

我正在尝试通过查询每个任务状态来获取任务链的进度。 但是当通过它的id检索链时,我会得到一些行为不同的对象。

在tasks.py

from celery import Celery

celery = Celery('tasks')
celery.config_from_object('celeryconfig')

def unpack_chain(nodes): 
    while nodes.parent:
        yield nodes.parent
        nodes = nodes.parent
    yield nodes

@celery.task
def add(num, num2):
    return num + num2

从ipython中查询...

In [43]: from celery import chain
In [44]: from tasks import celery, add, unpack_chain
In [45]: c = chain(add.s(3,3), add.s(10).set(countdown=100))
In [46]: m = c.apply_async()
In [47]: a = celery.AsyncResult(m.id)
In [48]: a == m
Out[48]: True
In [49]: a.id == m.id
Out[49]: True
In [50]: [t.status for t in list(unpack_chain(a))]
Out[50]: ['PENDING']
In [51]: [t.status for t in list(unpack_chain(m))]
Out[51]: ['PENDING', 'SUCCESS']

在Redis下使用Python 2.7.3和Celery 3.0.19。

正如您在 50& 51 celery.AsyncResult返回的值与原始链不同。

如何通过链ID获取原始链任务列表?

1 个答案:

答案 0 :(得分:9)

就像@Hernantz所说,你不能仅从任务ID中恢复父链,你必须遍历你的队列,这可能会也可能不会,这取决于你作为经纪人的用途。

但是如果您有最后一个任务ID来进行查找,那么您就拥有了链,只需要存储所有任务ID并在需要检查其状态时重建链。您可以使用以下功能:

def store(node):
    id_chain = []
    while node.parent:
      id_chain.append(node.id)
      node = node.parent
    id_chain.append(node.id)
    return id_chain

def restore(id_chain):
    id_chain.reverse()
    last_result = None
    for tid in id_chain:
        result = celery.AsyncResult(tid)
        result.parent = last_result
        last_result = result
    return last_result

首次从链中获取AsyncResult时调用存储。在上面调用恢复将为您提供链接的AsyncResult链接列表。