2016-08-23 23 views
-2

我正在创建一个应用程序,该应用程序将创建一个要执行的任务链,但链会根据用户对该片添加的愿望执行任务。如何在Celery中创建条件子任务链?

例如,如果用户想要start_boo链可能是:

def start_boo(): 
    chain = start_foo.s() | start_bar.s() | start_baz.s() 
    chain() 

但是,如果foobaz已经开始了,我们不希望这样做;而是宁愿是这样的:

def start_boo(foo=True, bar=True, baz=True): 
    if not (foo or bar or baz): 
     raise Exception("At least one should be true...") 
    chain = None 
    if foo: 
     chain |= start_foo.s() 
    if bar: 
     chain |= start_bar.s() 
    if baz: 
     chain |= start_baz.s() 
    chain() 

start_boo(foo=False, baz=False) 

然而,这不会因为各种原因工作。

有没有一个习惯做这样的事情?

+0

对于我的目标,我的理解和我的尝试,这似乎是一个非常有效的问题。请解释降价,以便我可以更好地提出问题。 – erip

回答

1

该成语是reduce函数从functools。您可以执行以下操作:

def start_boo(foo=True, bar=True, baz=True): 
    if not (foo or bar or baz): 
     raise Exception("At least one should be true...") 

    todo_tasks = [foo, bar, baz] 
    start_tasks = [start_foo, start_bar, start_baz] 

    # tasks contains start tasks which should be done per the options. 
    # if it's False in todo_tasks, its associated start_task isn't added 
    tasks = [start_task for todo, start_task in zip(todo_tasks, start_tasks) if todo] 
    first_task, rest = *tasks 

    # start with the first task to be completed and chain it with remaining tasks 
    chain = functools.reduce(lambda x, y: x | y.s(), rest, first_task.s()) 
    chain() 
+0

优秀的答案,但我不得不做一些小的调整。我会编辑你的答案。如果您不同意我的修改,请随时恢复。 – erip

+0

没关系,但我相信现在它可以是任务[1:]而不是编辑内的减少 –

+0

中的任务。再次感谢! – erip

相关问题