問題

私はセロリを使用してリモートサーバーにタスクを送信し、結果を取得しようとしています。タスクの状態は、リモートサーバー上の update_state メソッドを使用して常に更新されます。

私は使用してタスクを送信しています

 app.send_task('task_name')
 

セロリタスクの結果を取得することはブロッキング呼び出しであり、私はdjangoアプリが結果とタイムアウトを待つことを望んでいません。

だから私は結果を得るために別のセロリタスクを実行しようとしました。

 @app.task(ignore_result=True)
def catpure_res(task_id):
    task_obj = AsyncResult(task_id)
    task_obj.get(on_message=on_msg)
 

しかし、それは以下のエラーになります。

 Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/celery/app/trace.py", line 367, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/celery/app/trace.py", line 622, in __protected_call__
    return self.run(*args, **kwargs)
  File "/home/arpit/project/appname/tasks/results.py", line 42, in catpure_res
    task_obj.get(on_message=on_msg)
  File "/usr/local/lib/python2.7/dist-packages/celery/result.py", line 168, in get
    assert_will_not_block()
  File "/usr/local/lib/python2.7/dist-packages/celery/result.py", line 44, in assert_will_not_block
    raise RuntimeError(E_WOULDBLOCK)
RuntimeError: Never call result.get() within a task!
See http://docs.celeryq.org/en/latest/userguide/tasks.html#task-synchronous-subtasks
 

このエラーの回避策はありますか?結果を得るためにデーモンプロセスを実行する必要がありますか?

  ベストアンサー

allow_join_result を使用します。以下のスニペットを参照してください。

 @app.task(ignore_result=True)
def catpure_res(task_id):
    task_obj = AsyncResult(task_id)
    with allow_join_result():
        task_obj.get(on_message=on_msg)
 

注:他の回答で言及されているように、パフォーマンスの問題やデッドロックを引き起こす可能性がありますが、タスクがうまく書かれており、予期しないエラーが発生しない場合は、魅力的に機能するはずです。

  同じタグがついた質問を見る

pythondjangorediscelery