問題我已經將一個長期運行的任務劃分為多個邏輯子任務,因此我可以在每個子任務完成時報告結果。但是,我正在嘗試報告將永遠無法完成的任務的結果(而不是不斷產生價值),并且正在使用現有的解決方案來做到這一點。背景我正在為我編寫的某些Python程序構建Web界面。用戶可以通過Web表單提交作業,然后返回查看該作業的進度。假設我有兩個函數,每個函數可以通過單獨的形式進行訪問:med_func:執行大約需要1分鐘,結果傳遞給render(),這會產生其他數據。long_func:返回一個生成器。每次yield大約需要30分鐘,應向用戶報告。產量很多,我們可以認為此迭代器是無限的(僅在被撤銷時終止)。代碼,當前實現使用med_func,我報告結果如下:在表單提交時,我將保存AsyncResult到Django會話: task_result = med_func.apply_async([form], link=render.s()) request.session["task_result"] = task_result結果頁面的Django視圖訪問this AsyncResult。任務完成后,結果將保存到作為上下文傳遞給Django模板的對象中。def results(request): """ Serve (possibly incomplete) results of a session's latest run. """ session = request.session try: # Load most recent task task_result = session["task_result"] except KeyError: # Already cleared, or doesn't exist if "results" not in session: session["status"] = "No job submitted" else: # Extract data from Asynchronous Tasks session["status"] = task_result.status if task_result.ready(): session["results"] = task_result.get() render_task = task_result.children[0] # Decorate with rendering results session["render_status"] = render_task.status if render_task.ready(): session["results"].render_output = render_task.get() del(request.session["task_result"]) # Don't need any more return render_to_response('results.html', request.session)僅當函數實際終止時,此解決方案才有效。我無法將的邏輯子任務鏈接在一起long_func,因為存在未知數量的yields(每個循環long_func的循環可能不會產生結果)。題有什么明智的方法可以從極其長時間運行的Celery任務訪問生成的對象,以便可以在生成器用盡之前對其進行顯示?
3 回答

臨摹微笑
TA貢獻1982條經驗 獲得超2個贊
芹菜部分:
def long_func(*args, **kwargs):
i = 0
while True:
yield i
do_something_here(*args, **kwargs)
i += 1
@task()
def test_yield_task(task_id=None, **kwargs):
the_progress = 0
for the_progress in long_func(**kwargs):
cache.set('celery-task-%s' % task_id, the_progress)
Web客戶端,開始任務:
r = test_yield_task.apply_async()
request.session['task_id'] = r.task_id
測試最后的屈服值:
v = cache.get('celery-task-%s' % session.get('task_id'))
if v:
do_someting()
如果您不喜歡使用緩存或無法使用緩存,則可以使用db,文件或celery worker和服務器端都可以同時訪問的任何其他位置。使用緩存是最簡單的解決方案,但是工作人員和服務器必須使用相同的緩存。
添加回答
舉報
0/150
提交
取消