在文档中,@ celery.task装饰器不是传递参数,但在GitHub示例中,它被命名为“tasks.add”。为什么?当我删除名称时,该示例不再有效,抱怨
KeyError: '__main__.add'
[1] http://flask.pocoo.org/docs/0.10/patterns/celery/ [2] https://github.com/thrisp/flask-celery-example/blob/master/app.py#L25
答案 0 :(得分:4)
在Flask文档中,未设置任务name
,因为假定代码位于tasks
模块内,因此任务的名称将自动生成为{{1} },在Celery文档中:
每个任务都必须具有唯一名称,并且将生成新名称 如果未提供自定义名称,则不在函数名称中
查看Celery文档的Names部分以获取更多信息。
在Github的另一个例子中,作者明确地设置名称,而不是依赖于自动命名,如果作为主模块运行,则为tasks.add
,这是运行Flask服务器时的情况。 / p>
关于您遇到此问题的原因
更新:
当您通过__main__.tasks
和hello_world
访问/test
页面时,正在通过功能x
发送任务:
y
因为任务res = add.apply_async((x, y))
位于add
模块中,所以它将被命名为__main__
并以此名称发送给工作人员,但另一方面,您开始使用的工作人员:
__main__.add
此任务是否已注册为celery worker -A app.celery
,这就是您收到此错误的原因:
app.add
检查工人的输出:
[2014-10-10 10:32:29,540: ERROR/MainProcess] Received unregistered task of type '__main__.add'.
The message has been ignored and discarded.
Did you remember to import the module containing this task?
Or maybe you are using relative imports?
Please see http://docs.celeryq.org/en/latest/userguide/tasks.html#task-names for more information.
The full contents of the message body was:
{'timelimit': (None, None), 'utc': True, 'chord': None, 'args': (2787476, 36096995), 'retries': 0, 'expires': None, 'task': '__main__.add', 'callbacks': None, 'errbacks': None, 'taskset': None, 'kwargs': {}, 'eta': None, 'id': '804e10a0-2569-4338-a5e3-f9e07689d1d1'} (218b)
Traceback (most recent call last):
File "/home/peter/env/celery/lib/python2.7/site-packages/celery/worker/consumer.py", line 455, in on_task_received
strategies[name](message, body,
KeyError: '__main__.add'
Celery仅将任务名称发送给worker以执行它,因此当您显式设置任务名称时,[tasks]
. app.add
. celery.backend_cleanup
. celery.chain
. celery.chord
. celery.chord_unlock
. celery.chunks
. celery.group
. celery.map
. celery.starmap
函数将发送具有此名称的任务,该名称已在该worker中注册。
<强>更新强>:
任务名称可以是您想要的任何名称,它可以只是hello_world
,您的芹菜任务根本不必在add
模块中,以了解有关任务的更多信息名字试试这个:
删除显式任务名称并启动工作人员:
tasks
在另一个终端窗口中,celery worker -A app.celery
到代码目录并启动一个交互式python shell并试试这个:
cd
正如您所看到的,我们没有使用显式名称,并且它按预期工作,因为我们发送它的任务名称与在工作程序中注册的相同(见上文)。
现在回到你删除任务名称时出现此错误的原因,该任务从>>> import app
>>> app
<module 'app' from 'app.pyc'>
>>> app.add
<@task: app.add of app:0xb6a29a6c>
>>> # check the name of the task
... app.add.name
'app.add'
>>> t = app.add.delay(2, 3)
>>> t.result
5
发送,在同一目录下运行:
app.py
然后用$ python -i app.py
+ Ctrl
中断Flask服务器,试试这个:
C
正如您所看到的,这就是您收到此错误的原因,而不是因为您删除了任务名称。