Целевое задание сельдерея всегда ожидает

Я новичок в сельдерее и джанго в целом, поэтому, пожалуйста, извините за недостаток знаний. Я пытаюсь выполнить тест, чтобы выполнить некоторые вычисления, и дождаться завершения теста, чтобы я мог убедиться, что это сделано для правильных ответов.

Вот что у меня есть:

В 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

в приложении /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

Я также добавил CELERY_IGNORE_RESULT = False в файле mainapp/settings.py, но это ничего не делало.

Ответ 1

Итак, ваши настройки неверны.:) Вам также нужно настроить брокера на сельдерей для работы.

Прежде всего, djcelery устарел, все включено в celery, чтобы он работал с django.

Во-вторых, не устанавливайте весь контент, который может быть принят, это может быть потенциальным риском для безопасности. Используйте pickle только в том случае, если простого json недостаточно (допустим, вы передаете функции или объекты в качестве аргументов для задач или возвращаетесь из задач)

Итак, я предполагаю, что вы просто пытаетесь использовать сельдерей, почему вы пытаетесь использовать бэкэнд базы данных, что хорошо, но для использования в производстве я бы рекомендовал использовать RabbitMQ.

В любом случае, попробуйте с этими настройками:

BROKER_URL = 'django://'
INSTALLED_APPS = (
    ...
    'kombu.transport.django', 
    ...
)
CELERY_RESULT_BACKEND = 'db+scheme://user:[email protected]: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

Просто, чтобы вы знали, я не использовал базу данных в качестве брокерского или результирующего бэкэнда, поэтому настройка может быть неполной или даже неправильной, но в любом случае дайте ей попробовать.

больше 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'

Сообщите мне, как это происходит.

Ответ 2

Прямо из документа: Результат бэкэнд не работает или задачи всегда находятся в состоянии PENDING.

По умолчанию все задачи PENDING, поэтому состояние было бы лучше названо "неизвестно". Сельдерей не обновляет состояние при отправке задачи, и любая задача без истории считается ожидающей (вы знаете задачу id в конце концов).

  • Убедитесь, что задача не имеет ignore_result.

    Включение этой опции заставит работника пропускать состояния обновления.

  • Убедитесь, что параметр CELERY_IGNORE_RESULT не включен.

  • Убедитесь, что у вас еще нет старых рабочих.

    Легко запускать несколько сотрудников случайно, поэтому убедитесь, что предыдущий рабочий был правильно выключен, прежде чем вы начнете новый.

    Старый рабочий, который не настроен с ожидаемым результатом, может работать и увлекает задачи.

    Аргумент –pidfile может быть установлен в абсолютный путь, чтобы убедиться, что этого не происходит.

  • Убедитесь, что клиент настроен с правильным бэкэндом.

Если по какой-либо причине клиент настроен на использование другого бэкэнда, кроме рабочего, вы не сможете получить результат, поэтому убедитесь, что бэкэнд верен, проверив его:

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

Ответ 3

Если вы используете старые 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