django-celery-3.0.17、celery-3.0.21、django-1.5.1 を使用して、チェーンの実行を監視しようとしています。解決策を見つけましたが、少し奇妙に思えるので、可能であればより簡単な解決策を探しています。これが私のコードです:
ビュー.py
def runCod(request):
runFunTask = runFunctions.delay(shpId, codId, stepValues, bboxTuple);
getRunFunStatus.delay(runFunTask)
return render_to_response('tss/append_runCod.html',
{'runFunTask': runFunTask},
context_instance=RequestContext(request))
def getProgressCod(request):
task = AsyncResult(taskId)
currStep = task.result['step']
totSteps = task.result['total']
if task.status == 'SUCCESS':
task.revoke() # Manually terminate the runFunctions task
response = dumps({'status':task.status,'currStep':currStep,'totSteps':totSteps})
return HttpResponse(response, mimetype='application/json')
タスク.py
@task()
def runFunctions(shpId, codId, stepValues, bboxTuple):
# ... Code to define which functions to launch ...
stepsToLaunch = [fun1, fun2, fun3, fun4, fun5]
chainId = chain(stepsToLaunch).apply_async()
chainAsyncObjects = [node for node in reversed(list(nodes(chainId)))]
current_task.update_state(state="PROGRESS", meta={'step':1, 'total':numSteps})
for t in range(10800): # The same max duration of a celery task
for i, step in enumerate(chainAsyncObjects):
currStep = i+1
if step.state == 'PENDING':
current_task.update_state(state="PROGRESS", meta={'step':currStep, 'total':numSteps})
break
if step.state == 'SUCCESS':
if currStep == numSteps:
current_task.update_state(state="SUCCESS", meta={'step':currStep, 'total':numSteps})
# This task will be terminated (revoked) by getProgressCod()
if step.state == 'FAILURE':
return
sleep(1)
cods.js
function getProgressCod(taskId){
var aoiStatus, allStatus, currStep, totSteps;
var interval = 2000; // Perform ajax call every tot milliseconds
var refreshId = setInterval(function(){
$.ajax({
type: 'get',
url: 'getProgressCod/',
data:{'taskId': taskId,},
success: function(response){},
});
}, interval);
}
これが起こっていることです:
runCod()
非同期タスクを起動しますrunFunctions()
。runFunctions()
サブタスクのチェーンを作成して起動します- 最終ループで
runFunctions()
は、単一チェーンのサブタスクのステータスを見て、独自の「PROGRESS」ステータスを毎秒更新します。(参考文献1および2 ) - 何が起こっているかを知るために、ユーザーは
getProgressCod()
javascript 関数によって通知されます。この関数は、2 秒ごとにgetProcessCod()
Python 関数への ajax リクエストを行います。 getProcessCod()
python 関数はrunFunctions()
ステータスを見て、「SUCCESS」の場合はrunFunctions()
実行を取り消し (終了) します。
runFunctions()
チェーンのすべてのサブタスクが最終ループ内で完了したときに戻ると、オブジェクトが実行getProcessCod()
されるため、ユーザーに「成功」ステータスをユーザーに通知できないため、別の方法は見つかりませんでしたNone
task.status