新型芹菜api的问题 [英] Problems with the new style celery api

查看:54
本文介绍了新型芹菜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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆