web-dev-qa-db-ja.com

セロリタスクの状態は常に保留中

私はセロリにかなり慣れていません。Djangoなので、知識がないことをお許しください。いくつかの計算を行うためにテストを実行し、テストが完了するのを待って、それが正しい答えのために行われたことを確認してください。

ここに私が持っているものがあります:

App/tests.py内

from tasks import *


c = calculate.apply_async(args=[1])

# wait until the task is done
while not calculate.AsyncResult(c.id).status == "SUCCESS":
    print c.state
    pass

app/tasks.py

from celery import shared_task

@shared_task
def calculate(proj_id):

    #some calculations followed by a save of the object

セロリログにタスクが正常に完了したと表示されていても、状態が保留中から変化しない

[2014-06-10 17:55:11,417: INFO/MainProcess] Received task: app.tasks.calculate[1f11e7ab-0add-42df-beac-3d94c6868aac]
[2014-06-10 17:55:11,505: INFO/MainProcess] Task app.tasks.calculate[1f11e7ab-0add-42df-beac-3d94c6868aac] succeeded in 0.0864518239978s: None

また、mainapp/settings.pyにCELERY_IGNORE_RESULT = Falseを追加しましたが、これは何もしなかったようです。

18
DoctorWizard

そのため、設定が間違っています。 :)また、セロリが機能するようにブローカーを設定する必要があります。

まず、djceleryは非推奨です。celeryで動作するように、すべてがDjangoに含まれています。

次に、すべてのコンテンツを受け入れるように設定しないでください。これは、潜在的なセキュリティリスクになる可能性があります。 pickleは、単純なjsonでは不十分な場合にのみ使用してください(タスクに関数またはオブジェクトを引数として渡すか、タスクから戻るとしましょう)

だから私の推測では、セロリを試してみているだけです。それがデータベースバックエンドを使おうとしている理由ですが、本番環境ではRabbitMQの使用をお勧めします。

いずれにせよ、それらの設定を試してみてください:

BROKER_URL = 'Django://'
INSTALLED_APPS = (
    ...
    'kombu.transport.Django', 
    ...
)
CELERY_RESULT_BACKEND = 'db+scheme://user:password@Host:port/dbname' 
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_IGNORE_RESULT = False # this is less important

次にpython manage.py syncdbを実行します

ただお知らせするために、私はデータベースをブローカーまたは結果のバックエンドとして使用していません。そのため、セットアップが不完全であるか、正しくない場合もありますが、とにかく試してください。

more CELERY_RESULT_BACKENDデータベースの例の設定

RabbitMQをブローカーバックエンドとしてセットアップしたい場合は、これをお勧めします。

ubuntuで実行する場合:

Sudo apt-get install rabbitmq-server
Sudo rabbitmqctl add_user <username> <password>
Sudo rabbitmqctl add_vhost <vhost, use project name for example>
Sudo rabbitmqctl set_permissions -p <vhost> <username"> ".*" ".*" ".*"

次に、settings.pyでセロリを構成します。

BROKER_URL = 'amqp://<user>:<password>@localhost:5672/<vhost>'
CELERY_TIMEZONE = TIME_ZONE
CELERY_RESULT_BACKEND = 'amqp'
# thats where celery will store scheduled tasks in case you restart the broker:
CELERYD_STATE_DB = "/full/path/data/celery_worker_state" 
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

どうなるか教えてください。

6
lehins

ドキュメントから直接: 結果のバックエンドが機能しないか、タスクが常に[〜#〜] pending [〜#〜]状態です。

すべてのタスクはデフォルトでPENDINGであるため、状態の名前は「不明」の方が適切です。タスクが送信されても​​、Celeryは状態を更新せず、履歴のないタスクは保留中であると見なされます(結局、タスクidはわかっています)。

  1. タスクでignore_resultが有効になっていないことを確認してください。

    このオプションを有効にすると、ワーカーは状態の更新をスキップします。

  2. CELERY_IGNORE_RESULT設定が有効になっていないことを確認してください。

  3. 古いワーカーがまだ実行されていないことを確認してください。

    複数のワーカーを誤って開始するのは簡単なので、新しいワーカーを開始する前に、前のワーカーが適切にシャットダウンされていることを確認してください。

    期待される結果のバックエンドで構成されていない古いワーカーが実行されていて、タスクをハイジャックしています。

    –pidfile引数を絶対パスに設定して、これが発生しないようにすることができます。

  4. クライアントが正しいバックエンドで構成されていることを確認してください。

なんらかの理由でクライアントがワーカーとは異なるバックエンドを使用するように構成されている場合、結果を受け取ることができないため、バックエンドを調べて正しいことを確認します。

>>> result = task.delay(…)
>>> print(result.backend)
10
noooooooob

結果のバックエンドとして古いDjango-celeryおよびRabbitMQを使用している場合、これらの設定が役立つことがあります。

# Mostly, all settings are the same as in other answers

CELERY_RESULT_BACKEND = 'rpc://'
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_IGNORE_RESULT = False

# This line is what I needed
CELERY_TRACK_STARTED = True
0
Denis Krumko