1

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);
}

これが起こっていることです:

  1. runCod()非同期タスクを起動しますrunFunctions()
  2. runFunctions()サブタスクのチェーンを作成して起動します
  3. 最終ループでrunFunctions()は、単一チェーンのサブタスクのステータスを見て、独自の「PROGRESS」ステータスを毎秒更新します。(参考文献1および2 )
  4. 何が起こっているかを知るために、ユーザーはgetProgressCod()javascript 関数によって通知されます。この関数は、2 秒ごとにgetProcessCod()Python 関数への ajax リクエストを行います。
  5. getProcessCod()python 関数はrunFunctions()ステータスを見て、「SUCCESS」の場合はrunFunctions()実行を取り消し (終了) します。

runFunctions()チェーンのすべてのサブタスクが最終ループ内で完了したときに戻ると、オブジェクトが実行getProcessCod()されるため、ユーザーに「成功」​​ステータスをユーザーに通知できないため、別の方法は見つかりませんでしたNonetask.status

4

1 に答える 1