在Celery中,我正在運行一項主要任務,爲查詢中的每個項目運行一個子任務。子任務應該並行運行。在UI上,我有一個進度條,顯示總共完成了多少個子任務。我正在更新主任務狀態以將信息提供給進度條。我的問題是,在將所有子任務推送給經紀人後,主任務立即結束,因此我無法再更新他的狀態。我希望主要任務可以等到所有子任務完成。可能嗎?其他解決方案?這是我的僞代碼(真實代碼不使用全局;-))。在芹菜如何更新主任務的狀態,直到他所有的子任務完成?
total = 0
done = 0
@task(ignore_result=True)
def copy_media(path):
global total, done
copy_media.update_state(state=STARTED, meta={'total': total, 'done': done})
documents = Document.objects.all()
total = documents.count()
copy_media.update_state(state=STARTED, meta={'total': total, 'done': done})
for document in documents:
process_doc.delay(document, path, copy_media)
@task(ignore_result=True)
def process_doc(document, path, copy_media):
global total, done
# Do some stuff
done += 1
copy_media.update_state(state=STARTED, meta={'total': total, 'done': done})
正如文檔中明確指出的那樣:「讓一個任務等待另一個任務的結果真的是效率低下,甚至在工作池耗盡時甚至會導致死鎖 例如通過使用回調使設計異步。 「 http://celery.readthedocs.org/en/latest/userguide/tasks.html#task-synchronous-subtasks – antoinet 2015-06-25 15:09:24
我的主要任務'copy_media'沒有等待另一個任務的結果。它不斷更新狀態以顯示完成了多少子任務等。子任務並行運行,因此回調不是一個選項。最重要的是,我不能有死鎖,因爲'copy_media'一次只能運行一個,所以它只是阻止1個工作者。 – Etienne 2015-06-25 18:03:44
這是有效地等待其他任務的結果。你正在調用results.ready(),並且有一個任務正在測試其他人。如果你的工作人員疲憊不堪,你就會陷入僵局,因爲沒有任何子任務會被執行,你的主要任務將永遠不會結束。 – rsalmei 2016-10-03 17:31:41