新型芹菜api的问题 [英] Problems with the new style celery api
问题描述
我有一个扩展芹菜 Task
的类.可以在旧样式的API上正常运行,但是在将其转换为新的API时遇到问题.
#在app/tasks.py中从芹菜进口芹菜,任务芹菜=芹菜()@ celery.task类CustomTask(Task):def run(self,x):尝试:# 做一点事除例外,e:self.retry(args = [x],exc = e)
然后我像这样运行任务-
CustomTask().apply_async(args = [x],queue ='q1')
我得到了错误-
TypeError:run()恰好接受2个参数(给定1个)
此SO答案似乎在做同样的事情,因此被认为可以正常工作.谁能帮助我并向我解释为什么我的代码不起作用?
编辑
如果我给任务命名,这与类名不同-
name ='app.tasks.CustomTask2'
但是,如果我将任务的名称与完整的类名保持一致,那就行不通了
name ='app.tasks.CustomTask'
但是名称不同的问题是,芹菜还有一个额外的任务,与任务类的名称相同.
装饰器不与类一起使用,而是用于函数.
通常,除非要实现常见行为,否则您将不想定义自定义任务类.
因此,请删除 @ celery.task
装饰器,或将其与功能一起使用.
请注意,您在此处定义的任务未与任何celery实例绑定
注意绑定到任何特定的应用实例:
芹菜导入任务中的 类MyTask(Task):经过
您以后可以绑定它:
从芹菜进口芹菜应用=芹菜(经纪人='amqp://')MyTask.bind(app)
或者您可以使用应用程序上可用的基类:
从芹菜进口芹菜应用=芹菜(经纪人='amqp://')类MyTask(app.Task):经过
最后一个例子不是很干净,因为这意味着您要在模块级别完成应用程序的确定,这是为什么将任务装饰器与函数一起使用是最佳实践,并且仅创建自定义类以用作装饰任务的基类的另一个原因( @task(base = MyTask)
).>
I have a class that extends celerys Task
. It runs just fine with the old style API, but I am having problems converting it to the new API.
# In app/tasks.py
from celery import Celery, Task
celery = Celery()
@celery.task
class CustomTask(Task):
def run(self, x):
try:
# do something
except Exception, e:
self.retry(args=[x], exc=e)
And then I run the task like so -
CustomTask().apply_async(args=[x], queue='q1')
And I get the error -
TypeError: run() takes exactly 2 arguments (1 given)
This SO answer seems to do the same thing and it was accepted so presumably it works. Can anyone help me out and explain to me why my code isn't working?
EDIT
This works if I name the task, different from the class name -
name = 'app.tasks.CustomTask2'
But if I keep the name of the task the same as the full class name, it doesn't work
name = 'app.tasks.CustomTask'
But the problem with having a different name is that celery has an extra task, with the same name as the task class name.
The decorator is not used with classes, it's used for functions.
Usually you will not want to define custom task classes unless you want to implement common behavior.
So either remove the @celery.task
decorator, or use it with a function.
Note that the task you define here is not bound with any celery instance
Note bound to any specific app instance:
from celery import Task
class MyTask(Task):
pass
You can bind it later:
from celery import Celery
app = Celery(broker='amqp://')
MyTask.bind(app)
or you can use the base class available on the app:
from celery import Celery
app = Celery(broker='amqp://')
class MyTask(app.Task):
pass
The last example is not very clean as it means you are finalizing the app at module level,
this is another reason why using the task decorator with functions is a best practice, and only create custom classes to be used as a base class for decorated tasks (@task(base=MyTask)
).
这篇关于新型芹菜api的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!