芹菜任务状态总是待定

时间:2014-06-10 18:53:01

标签: python django celery django-celery celery-task

我对芹菜和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,但这似乎没有做任何事情。

3 个答案:

答案 0 :(得分:9)

直接来自doc:Result backend does not work or tasks are always in PENDING state.

默认情况下,所有任务都为PENDING,因此状态更好地命名为“未知”。 Celery在发送任务时不会更新任何状态,并且任何没有历史记录的任务都被认为是待处理的(毕竟你知道任务id。)

  1. 确保该任务未启用ignore_result

    启用此选项将强制工作人员跳过更新状态。

  2. 确保未启用CELERY_IGNORE_RESULT设置。

  3. 确保您没有任何旧工作人员仍在运行。

    偶然启动多个工作人员很容易,因此请确保在开始新工作之前正确关闭前一个工作人员。

    未配置预期结果后端的旧工作程序可能正在运行并且正在劫持任务。

    可以将–pidfile参数设置为绝对路径,以确保不会发生这种情况。

  4. 确保客户端配置了正确的后端。

  5. 如果由于某种原因客户端被配置为使用与工作人员不同的后端,您将无法收到结果,因此请检查后端是否正确:

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

答案 1 :(得分:6)

所以,你的设置是错误的。 :)你还需要为芹菜设置经纪人才能工作。

首先,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 setting for database examples

如果您想将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 :(得分:0)

如果您使用旧的django-celeryRabbitMQ作为结果后端,那么这些设置可能有所帮助:

# 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