Django Celery教程没有返回结果

seq*_*oia 11 python django rabbitmq celery

UDATE3:发现了这个问题.请参阅以下答案.

UPDATE2:似乎我可能通过manage.py shell运行djcelery教程来处理自动命名和相对导入问题,见下文.它仍然不适合我,但现在我收到新的日志错误消息.见下文.

更新:我在帖子的底部添加了日志.似乎示例任务没有注册?

原帖:

我想让django-芹菜起来跑步.我无法通过这个例子.

我成功安装了rabbitmq,并且没有遇到任何麻烦:http://www.rabbitmq.com/getstarted.html

然后我尝试通过djcelery教程.

当我运行时,python manage.py celeryd -l info我收到消息:[任务] - app.module.add [2011-07-27 21:17:19,990:警告/主程序]芹菜@sequoia已经启动.

所以看起来不错.我把它放在我的设置文件的顶部:

import djcelery
djcelery.setup_loader()

BROKER_HOST = "localhost"
BROKER_PORT = 5672
BROKER_USER = "guest"
BROKER_PASSWORD = "guest"
BROKER_VHOST = "/"
Run Code Online (Sandbox Code Playgroud)

将这些添加到我安装的应用中:

'djcelery',
Run Code Online (Sandbox Code Playgroud)

这是我的app的tasks文件夹中的tasks.py文件:

from celery.task import task

@task()
def add(x, y):
    return x + y
Run Code Online (Sandbox Code Playgroud)

我把它添加到我的django.wsgi文件中:

os.environ["CELERY_LOADER"] = "django"
Run Code Online (Sandbox Code Playgroud)

然后我在命令行输入了这个:

>>> from app.module.tasks import add
>>> result = add.delay(4,4)
>>> result
(AsyncResult: 7auathu945gry48- a bunch of stuff)
>>> result.ready()
False
Run Code Online (Sandbox Code Playgroud)

所以看起来它有效,但问题是:

>>> result.result
>>>               (nothing is returned)
>>> result.get()
Run Code Online (Sandbox Code Playgroud)

当我输入result.get()时它就会挂起.我究竟做错了什么?

更新:这是在我启动工作服务器时在前台运行记录器的原因:

No handlers could be found for logger “multiprocessing”

[Configuration]
- broker:      amqplib://guest@localhost:5672/
- loader:      djcelery.loaders.DjangoLoader
- logfile:     [stderr]@INFO
- concurrency: 4
- events:      OFF
- beat:        OFF

[Queues]
- celery:      exchange: celery (direct)  binding: celery

[Tasks]
 - app.module.add
[2011-07-27 21:17:19, 990: WARNING/MainProcess] celery@sequoia has started.

 C:\Python27\lib\site-packages\django-celery-2.2.4-py2.7.egg\djcelery\loaders.py:80:  UserWarning: Using settings.DEBUG leads to a memory leak, neveruse this setting in production environments!
     warnings.warn(“Using settings.DEBUG leads to a memory leak, never”
Run Code Online (Sandbox Code Playgroud)

然后当我输入命令时:

>>> result = add(4,4)
Run Code Online (Sandbox Code Playgroud)

这出现在错误日志中:

[2011-07-28 11:00:39, 352: ERROR/MainProcess] Unknown task ignored: Task of kind ‘task.add’ is not registered, please make sure it’s imported. Body->”{‘retries’: 0, ‘task’: ‘tasks.add’, ‘args’: (4,4), ‘expires’: None, ‘ta’: None
    ‘kwargs’: {}, ‘id’: ‘225ec0ad-195e-438b-8905-ce28e7b6ad9’}”
Traceback (most recent call last):
   File “C:\Python27\..\celery\worker\consumer.py”,line 368, in receive_message
      Eventer=self.event_dispatcher)
   File “C:\Python27\..\celery\worker\job.py”,line 306, in from_message 
       **kw)
   File “C:\Python27\..\celery\worker\job.py”,line 275, in __init__
       self.task = tasks[self.task_name]
   File “C:\Python27\...\celery\registry.py”, line 59, in __getitem__
       Raise self.NotRegistered(key)
NotRegistered: ‘tasks.add’   
Run Code Online (Sandbox Code Playgroud)

如何正确注册和处理此任务?谢谢.

更新2:

此链接表明未注册的错误可能是由于客户端和工作人员之间的任务名称不匹配 - http://celeryproject.org/docs/userguide/tasks.html#automatic-naming-and-relative-imports

退出manage.py shell并输入python shell并输入以下内容:

>>> from app.module.tasks import add
>>> result = add.delay(4,4)
>>> result.ready()
False
>>> result.result
>>>                 (nothing returned)
>>> result.get()
                    (it just hangs there)
Run Code Online (Sandbox Code Playgroud)

所以我得到了相同的行为,但新的日志消息.从日志中可以看出服务器正在运行,但它不会反馈结果:

[2011-07-28 11:39:21, 706: INFO/MainProcess] Got task from broker: app.module.tasks.add[7e794740-63c4-42fb-acd5-b9c6fcd545c3]
[2011-07-28 11:39:21, 706: INFO/MainProcess] Task app.module.tasks.add[7e794740-63c4-42fb-acd5-b9c6fcd545c3] succeed in 0.04600000038147s: 8
Run Code Online (Sandbox Code Playgroud)

所以服务器得到了任务,它计算出正确的答案,但它不会发送回去?为什么不?

seq*_*oia 14

我从另一个stackoverflow帖子中找到了我的问题的解决方案:为什么Celery在Python shell中工作,而不是在我的Django视图中?(进口问题)

我必须将这些行添加到我的设置文件中:

CELERY_RESULT_BACKEND = "amqp"
CELERY_IMPORTS = ("app.module.tasks", )
Run Code Online (Sandbox Code Playgroud)

然后在task.py文件中我将任务命名为:

@task(name="module.tasks.add")
Run Code Online (Sandbox Code Playgroud)

必须通知服务器和客户端任务名称.celery和django-celery教程在他们的教程中省略了这些行.

  • @Tony在http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html#defining-and-calling-tasks下面看到关于相对进口的说明除非你使用,否则它不是问题Python中不鼓励相对导入和相对导入 (2认同)