2015-11-06 105 views
3

我是Python芹菜的新手,並嘗試使用Celery進行工作流執行。工作流程:Task workflowPython芹菜任務工作流程excution

在附圖中,我試圖展示下文在文中解釋的工作流程。

  1. 客戶端調用Task-1。
  2. 成功執行任務1時,執行任務2和任務3(同時),並在任務1失敗時執行任務4。
  3. 成功執行任務2時,執行任務5和任務6(同時),並在任務2失敗時執行任務7。
  4. 任務-5成功後,執行大量(100s)Task-8(同時),如果Task-5失敗,則執行Task-9。

當客戶端調用Task-1時,會傳遞一個參數,該參數在成功和失敗情況下傳遞給下一個任務。

我明白Canvas可以用來設計一個Celery的工作流程。但是,我無法弄清楚如何在不同層次的成功和失敗的情況下開展如此大的工作流程。請建議我應該如何使用Celery和Canvas來規劃這樣的工作流程。 任何用於教程或示例的鏈接都將非常有幫助。

回答

0

您可以有一個包裝任務來處理調用其他任務的邏輯。

你的代碼可能會結束這樣的事情。

@celery.task(name='tasks.wrapper_task') 
def wrapper_task(one_arg): 
    if task_one(one_arg): 
     task_three.apply_async(arg_one) 
     if task_two(arg_one): 
      task_six.apply_async(arg_one) 
      if task_five(arg_one): 
       task_eight.apply_async(1) 
       task_eight.apply_async(2) 
       # etc... 
      else: 
       task_nine(arg_one) 
     else: 
      task_seven(arg_one) 
    else: 
     task_four(arg_one) 

我還沒有爲您定義所有任務。正如你所看到的,除非你需要在其他情況下異步調用它們,否則不是所有的都需要芹菜任務。

我採取'失敗'表示退貨虛假,但您可以輕鬆地修改代碼以使用try/except

+0

感謝李的包裝任務的想法。 –

3

你有沒有試過類似的東西? (僞代碼)

workflow = (t1.s().set(link_error=t4.s()) | 

      group((t2.s().set(link_error=t7.s()) | 

        group(t6.s(), 
         (t5.s().set(link_error=t9.s()) | 
         group(t8.s(i) for i in xrange(100)))), 

        t3.s()) 
      ) 
).apply_async() 

link_error是錯誤的回調。

http://docs.celeryproject.org/en/latest/userguide/canvas.html

+0

問題不在於在任務內啓動(「調用」)任務,而是在任務內部等待任務(通常這也意味着啓動它)。 [本頁]上的警告(http://docs.celeryproject.org/en/latest/reference/celery.result.html)很清楚。不幸的是,文檔[here](http://docs.celeryproject.org/en/latest/userguide/tasks.html#task-synchronous-subtasks)談到了「啓動同步子任務」。這可能導致認爲「啓動」部分是問題,但真正的問題是「同步」,這意味着等待任務。李的回答沒有等待。 – Louis

+0

「if task_two(arg_one)」:這應該等待任務結束。 問題是非常明確的工作流程。見圖片。如果前面的任務成功完成,任務將按順序執行。我稱之爲等待,我不確定你的意思是「沒有等待」 –

+0

調用像你這樣的任務顯示('task_two(...)')完全繞過工作人員。它是[這裏]描述的'__call__'方法(http://docs.celeryproject.org/en/latest/userguide/calling。html):「意味着任務將在當前進程中執行,而不是由工作人員執行(不會發送消息)。」沒有等待。如果你想調用這個「同步」,那很好,但它不是我前面提到的芹菜文檔中討論的「同步」。 * *同步是關於由工作人員*運行任務*並立即*等待*。 – Louis