使用依赖关系图执行Celery任务

时间:2011-07-05 09:39:56

标签: python celery

我希望Celery的任务取决于2个或更多其他任务的结果。我查看了Python+Celery: Chaining jobs?http://pypi.python.org/pypi/celery-tasktree,但只有当任务只有一个相关任务时,这些才有用。

我了解TaskSet,但是当TaskSetResult.ready()变为True时,似乎没有办法立即执行回调。我现在想到的是有一个周期性的任务,每隔几[毫秒]左右轮询一次TaskSetResult.ready()并在返回True时触发回调,但这对我来说听起来相当不优雅。

有什么建议吗?

3 个答案:

答案 0 :(得分:9)

在Celery(3.0+)的最新版本中,你可以使用所谓的和弦来达到预期的效果:

来自http://docs.celeryproject.org/en/latest/userguide/canvas.html#the-primitives

  

简单的和弦

     

chord原语使我们能够添加回调以便在所有时调用   组中的任务已经完成执行,这通常是   算法并不是令人尴尬地并行:

 >>> from celery import chord
 >>> res = chord((add.s(i, i) for i in xrange(10)), xsum.s())()
 >>> res.get()
 90

免责声明:我自己还没试过。

答案 1 :(得分:3)

mrbox是真的,你可以重试直到结果准备就绪,但是在文档中不太清楚,当你重试时你必须传递setid和子任务元素,并且为了恢复它你必须使用map函数,下面有一个示例代码,用于解释我的意思。

def run(self, setid=None, subtasks=None, **kwargs):

    if not setid or not subtasks:
        #Is the first time that I launch this task, I'm going to launch the subtasks
        …
        tasks = []
        for slice in slices:
            tasks.append(uploadTrackSlice.subtask((slice,folder_name)))

        job = TaskSet(tasks=tasks)
        task_set_result = job.apply_async()
        setid = task_set_result.taskset_id
        subtasks = [result.task_id for result in task_set_result.subtasks]
        self.retry(exc=Exception("Result not ready"), args=[setid,subtasks])

    #Is a retry than we just have to check the results        
    tasks_result = TaskSetResult(setid, map(AsyncResult,subtasks))
    if not tasks_result.ready():
        self.retry(exc=Exception("Result not ready"), args=[setid,subtasks])
    else:    
        if tasks_result.successful():
            return tasks_result.join()
        else:
            raise Exception("Some of the tasks was failing")

答案 2 :(得分:2)

恕我直言,你可以做类似于docs- link

中完成的事情

或者你可以使用max_retries = None的重试方法 - 如果其中一个'基本'任务.ready()为false,你可以触发.retry()方法直到两个'基础'任务完成。