web-dev-qa-db-ja.com

Celeryでタスクのステータスを確認する方法は?

タスクがセロリで実行されているかどうかを確認するにはどうすればよいですか(具体的には、celery-Djangoを使用しています)?

私はドキュメントを読み、グーグルで検索しましたが、次のような呼び出しが表示されません:

my_example_task.state() == RUNNING

私のユースケースは、トランスコーディング用の外部(Java)サービスがあることです。トランスコードするドキュメントを送信するとき、そのサービスを実行するタスクが実行されているかどうかを確認し、実行されていない場合は、それを(再)開始します。

現在の安定バージョン-2.4を使用しています。

84
Marcin

すべてのTaskオブジェクトには、AsyncRequestオブジェクトを含む.requestプロパティがあります。したがって、次の行はタスクtaskの状態を示します。

task.AsyncResult(task.request.id).state
56
Marcin

Task_id(.delay()から提供されます)を返し、後でセロリインスタンスに状態を問い合わせます。

x = method.delay(1,2)
print x.task_id

尋ねるとき、このtask_idを使用して新しいAsyncResultを取得します。

from celery.result import AsyncResult
res = AsyncResult("your-task-id")
res.ready()
82
Gregor

タスクIDからAsyncResultオブジェクトを作成するisFAQ で推奨されている方法は、タスクIDのみが存在する場合にタスクステータスを取得します。

ただし、Celery 3.xの時点では、注意を払わないと人々に噛みつく重大な警告があります。それは本当に特定のユースケースシナリオに依存します。

デフォルトでは、Celeryは「実行中」状態を記録しません。

Celeryがタスクの実行を記録するには、 task_track_startedTrueに設定する必要があります。これをテストする簡単なタスクを次に示します。

@app.task(bind=True)
def test(self):
    print self.AsyncResult(self.request.id).state

task_track_startedがデフォルトのFalseである場合、タスクが開始されていても、状態表示はPENDINGです。 task_track_startedTrueに設定すると、状態はSTARTEDになります。

状態PENDINGは「わからない」という意味です。

状態がAsyncResultPENDINGは、Celeryがタスクのステータスを認識していないという意味ではありません。これには、さまざまな理由が考えられます。

1つには、無効なタスクIDを使用してAsyncResultを構築できます。そのような「タスク」は、Celeryによって保留中と見なされます。

>>> task.AsyncResult("invalid").status
'PENDING'

わかりましたので、誰も明らかに無効なIDをAsyncResultにフィードしません。結構ですが、AsyncResultも正常に実行されたタスクを考慮しますが、CeleryはPENDINGであることを忘れていました。繰り返しますが、 一部のユースケースシナリオこれは問題になる可能性があります。問題の一部は、結果のバックエンドの「墓石」の可用性に依存するため、タスクの結果を保持するためのCeleryの構成方法にかかっています。 (「廃棄」は、タスクの終了方法を記録するデータチャンクのCeleryドキュメントでの用語の使用です。) task_ignore_resultAsyncResultの場合、Trueを使用してもまったく機能しません。さらに厄介な問題は、Celeryがデフォルトで廃棄標識を期限切れにすることです。 result_expires 設定はデフォルトで24時間に設定されています。したがって、タスクを起動し、長期ストレージにIDを記録し、さらに24時間後に、それを使用してAsyncResultを作成すると、ステータスはPENDINGになります。

すべての「実際のタスク」は、PENDING状態で開始されます。そのため、タスクでPENDINGを取得するということは、タスクが要求されたが、これよりも先に進まなかったことを意味します(何らかの理由で)。または、タスクは実行されたが、セロリがその状態を忘れたことを意味する可能性があります。

痛い! AsyncResultは機能しません。他に何ができますか?

タスク自体を追跡するよりもgoalsを追跡することを好みます。私はいくつかのタスク情報を保持していますが、それは本当に目標を追跡することに二次的です。目標はCeleryから独立したストレージに保存されます。要求が計算を実行する必要がある場合、達成された何らかの目標に依存し、目標がすでに達成されているかどうかを確認し、はいの場合はこのキャッシュされた目標を使用し、そうでない場合は目標に影響するタスクを開始して、に送信しますHTTPリクエストを、結果を待つ必要があることを示す応答にしたクライアント。


上記の変数名とハイパーリンクは、Celery 4.x用です。 3.xでは、対応する変数とハイパーリンクは CELERY_TRACK_STARTEDCELERY_IGNORE_RESULTCELERY_TASK_RESULT_EXPIRES です。

54
Louis

カスタム状態を作成し、タスク実行中にその値を更新することもできます。この例はドキュメントからのものです:

@app.task(bind=True)
def upload_files(self, filenames):
    for i, file in enumerate(filenames):
        if not self.request.called_directly:
            self.update_state(state='PROGRESS',
                meta={'current': i, 'total': len(filenames)})

http://celery.readthedocs.org/en/latest/userguide/tasks.html#custom-states

15
msangel

古い質問ですが、最近この問題に遭遇しました。

Task_idを取得しようとしている場合は、次のように実行できます。

import celery
from celery_app import add
from celery import uuid

task_id = uuid()
result = add.apply_async((2, 2), task_id=task_id)

これでtask_idが何であるかを正確に把握し、それを使用してAsyncResultを取得できるようになりました。

# grab the AsyncResult 
result = celery.result.AsyncResult(task_id)

# print the task id
print result.task_id
09dad9cf-c9fa-4aee-933f-ff54dae39bdf

# print the AsyncResult's status
print result.status
SUCCESS

# print the result returned 
print result.result
4
9
Cesar Rios

celery FAQ からこのAPIを使用するだけです

result = app.AsyncResult(task_id)

これは正常に機能します。

4
David Ding

単純なタスクには、 http://flower.readthedocs.io/en/latest/screenshots.html および http://policystat.github.io/jobtastic/ を使用できます=監視を行います。

複雑なタスクの場合は、他の多くのモジュールを扱うタスクを言います。特定のタスクユニットで進行状況とメッセージを手動で記録することをお勧めします。

0
taotao.li

試してください:

task.AsyncResult(task.request.id).state

これにより、Celeryタスクのステータスが提供されます。 Celery TaskがすでにFAILURE stateにある場合、例外をスローします:

raised unexpected: KeyError('exc_type',)

0
user260826

上記のプログラムによるアプローチとは別に、Flower Taskの使用状況は簡単に確認できます。

Celery Eventsを使用したリアルタイム監視。 Flowerは、Celeryクラスターを監視および管理するためのWebベースのツールです。

  1. タスクの進捗と履歴
  2. タスクの詳細(引数、開始時間、実行時間など)を表示する機能
  3. グラフと統計

公式文書: 花-セロリ監視ツール

インストール:

$ pip install flower

使用法:

http://localhost:5555
0
Roshan Bagdiya

役立つ情報を見つけました

Celery Project Workers Guide inspecting-workers

私の場合、Celeryが実行されているかどうかを確認しています。

inspect_workers = task.app.control.inspect()
if inspect_workers.registered() is None:
    state = 'FAILURE'
else:
    state = str(task.state) 

Inspectを使用して、ニーズを取得できます。

0
zerocog