私はセロリにかなり慣れていません。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を追加しましたが、これは何もしなかったようです。
そのため、設定が間違っています。 :)また、セロリが機能するようにブローカーを設定する必要があります。
まず、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'
どうなるか教えてください。
ドキュメントから直接: 結果のバックエンドが機能しないか、タスクが常に[〜#〜] pending [〜#〜]状態です。
すべてのタスクはデフォルトでPENDING
であるため、状態の名前は「不明」の方が適切です。タスクが送信されても、Celeryは状態を更新せず、履歴のないタスクは保留中であると見なされます(結局、タスクid
はわかっています)。
タスクでignore_result
が有効になっていないことを確認してください。
このオプションを有効にすると、ワーカーは状態の更新をスキップします。
CELERY_IGNORE_RESULT
設定が有効になっていないことを確認してください。
古いワーカーがまだ実行されていないことを確認してください。
複数のワーカーを誤って開始するのは簡単なので、新しいワーカーを開始する前に、前のワーカーが適切にシャットダウンされていることを確認してください。
期待される結果のバックエンドで構成されていない古いワーカーが実行されていて、タスクをハイジャックしています。
–pidfile
引数を絶対パスに設定して、これが発生しないようにすることができます。
クライアントが正しいバックエンドで構成されていることを確認してください。
なんらかの理由でクライアントがワーカーとは異なるバックエンドを使用するように構成されている場合、結果を受け取ることができないため、バックエンドを調べて正しいことを確認します。
>>> result = task.delay(…)
>>> print(result.backend)
結果のバックエンドとして古い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