在烧瓶的芹菜文档中,为什么芹菜任务需要名字?

时间:2014-10-09 07:31:10

标签: python flask celery celery-task

在文档中,@ 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

1 个答案:

答案 0 :(得分:4)

在Flask文档中,未设置任务name,因为假定代码位于tasks模块内,因此任务的名称将自动生成为{{1} },在Celery文档中:

  

每个任务都必须具有唯一名称,并且将生成新名称   如果未提供自定义名称,则不在函数名称中

查看Celery文档的Names部分以获取更多信息。

在Github的另一个例子中,作者明确地设置名称,而不是依赖于自动命名,如果作为主模块运行,则为tasks.add,这是运行Flask服务器时的情况。 / p> 关于您遇到此问题的原因

更新

当您通过__main__.taskshello_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

正如您所看到的,这就是您收到此错误的原因,而不是因为您删除了任务名称。