2013-07-12 80 views
2

問題我有一個延伸celerys Task類。它使用舊式API運行得很好,但我在將它轉換爲新的API時遇到了問題。與新的風格芹菜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) 

然後我運行的任務,像這樣 -

CustomTask().apply_async(args=[x], queue='q1') 

而我得到的錯誤 -

TypeError: run() takes exactly 2 arguments (1 given) 

This SO answer似乎做同樣的事情,它是接受這樣想必作品。任何人都可以幫我解釋一下爲什麼我的代碼不工作?

編輯

如果我命名的任務,從類名稱不同這工作 -

name = 'app.tasks.CustomTask2' 

但是,如果我把任務的名稱相同類的全名,它不工作

name = 'app.tasks.CustomTask' 

但與具有不同的名稱問題是,芹菜有一個額外的任務,具有相同的名稱作爲任務班級名稱。

+0

爲什麼你需要'芹菜=芹菜()'?嗯,沒關係,它在文檔中,儘管它不適用於它。使用功能,他們這樣工作。 – gatto

+0

我不知道。我正在嘗試這個,希望它可以工作,當我發佈這個。我已經嘗試過了,而沒有'celery = Celery()',它仍然給出了同樣的錯誤。 – elssar

+0

是用'進口celery','@ celery.task'和'celery.Task' – elssar

回答

2

裝飾器不用於類,它用於功能。

通常,你不會想,除非你想實現共同的行爲來定義自定義任務類。

所以,要麼去除@celery.task裝飾,或者用一個函數中使用它。

請注意,您在此處定義任務不與任何芹菜實例綁定

注意綁定到任何特定的應用程序實例:

from celery import Task 

class MyTask(Task): 
    pass 

您可以稍後將它綁定:

from celery import Celery 
app = Celery(broker='amqp://') 

MyTask.bind(app) 

或者您可以使用基類可用的應用程序:

from celery import Celery 
app = Celery(broker='amqp://') 

class MyTask(app.Task): 
    pass 

的最後一個例子不是很乾淨,因爲它意味着你在模塊級敲定應用, 這就是爲什麼使用與功能任務裝飾是一個最佳實踐的另一個原因,只有創建自定義類用作基地裝飾任務類(@task(base=MyTask))。