AsyncResult
タスクIDからオブジェクトを作成することは、 FAQで推奨されている方法であり、タスクIDしか持っていない場合にタスクのステータスを取得します。
ただし、Celery 3.xの時点では、注意を払わないと人々を噛む可能性のある重大な警告があります。それは実際には特定のユースケースシナリオに依存します。
デフォルトでは、Celeryは「実行中」の状態を記録しません。
Celeryがタスクの実行を記録するには、に設定task_track_started
する必要がありますTrue
。これをテストする簡単なタスクは次のとおりです。
@app.task(bind=True)
def test(self):
print self.AsyncResult(self.request.id).state
task_track_started
がFalse
デフォルトの場合、タスクが開始されていても状態が表示さPENDING
れます。に設定task_track_started
するTrue
と、状態はになりますSTARTED
。
状態PENDING
は「わからない」という意味です。
AsyncResult
状態のあるとPENDING
は、Celeryがタスクのステータスを知らないということ以上の意味はありません。これは、さまざまな理由が原因である可能性があります。
一つにAsyncResult
は、無効なタスクIDで構築できます。このような「タスク」は、Celeryによって保留中と見なされます。
>>> task.AsyncResult("invalid").status
'PENDING'
わかりました。明らかに無効なIDをにフィードする人は誰もいませんAsyncResult
。十分に公平ですが、それはまたAsyncResult
、正常に実行されたが、Celeryがであると忘れているタスクを考慮する効果もありますPENDING
。繰り返しますが、一部のユースケースシナリオでは、これが問題になる可能性があります。問題の一部は、結果バックエンドでの「トゥームストーン」の可用性に依存するため、タスクの結果を保持するようにCeleryがどのように構成されているかにかかっています。(「トゥームストーン」は、タスクがどのように終了したかを記録するデータチャンクのCeleryドキュメントでの使用という用語です。)の場合、使用はAsyncResult
まったく機能しません。さらに厄介な問題は、Celeryがデフォルトでトゥームストーンを期限切れにすることです。ザtask_ignore_result
True
result_expires
デフォルトの設定は24時間に設定されています。したがって、タスクを起動し、IDを長期保存に記録し、24時間後にそれを使用して作成するAsyncResult
と、ステータスはになりますPENDING
。
すべての「実際のタスク」はそのPENDING
状態で始まります。したがってPENDING
、タスクに参加するということは、タスクが要求されたが、(何らかの理由で)これ以上進行しなかったことを意味する可能性があります。または、タスクは実行されたが、Celeryがその状態を忘れたことを意味する場合があります。
痛い!AsyncResult
私にはうまくいきません。他に何ができますか?
タスク自体を追跡するよりも、目標を追跡する方が好きです。私はいくつかのタスク情報を保持していますが、それは本当に目標を追跡することの二次的なものです。目標は、Celeryから独立したストレージに保存されます。リクエストが達成された目標に応じて計算を実行する必要がある場合、目標がすでに達成されているかどうかを確認します。達成されている場合は、このキャッシュされた目標を使用します。それ以外の場合は、目標に影響を与えるタスクを開始し、に送信します。 HTTP要求を行ったクライアントは、結果を待つ必要があることを示す応答を要求しました。
上記の変数名とハイパーリンクはCelery4.x用です。3.xでは、対応する変数とハイパーリンクは次のとおりです。 CELERY_TRACK_STARTED
、、。CELERY_IGNORE_RESULT
CELERY_TASK_RESULT_EXPIRES