2016-11-11 113 views
1

基於以下示例:芹菜4.0.0和基於任務的任務工作流程

http://shulhi.com/class-based-celery-task/;

https://blog.balthazar-rouberol.com/celery-best-practices

http://shulhi.com/class-based-celery-task/

Class based Task in django celery

我想創建類似的東西:

class CalculationWorker(Task): 

    def __init__(self, id_user): 
     self._id_user = id_user 
     self._user = get_object_or_404(User, pk=self._id_user) 

    # I need to understand if the bind work or if it's needed 
    def _bind(self, app): 
     return super(self.__class__, self).bind(celery_app) 

    def _retrieve_some_task(self): 
     # long calculation 

    def _long_run_task(self): 
     # long calculation 
     self._retrieve_some_task() 

    # Main entry 
    def run(self): 
     self._long_run_task() 


# 
def run_job(): 
    worker = CalculationWorker(id_user=323232) 
    task = worker.apply_async() 

的文件似乎說這是可能的(反正這是我不清楚)http://docs.celeryproject.org/en/latest/userguide/tasks.html#custom-task-classes 。它甚至說:

「」」 這意味着初始化構造僅會被每個進程調用,該任務類在語義上更接近演員 。‘’

http://docs.celeryproject.org/en/latest/whatsnew-4.0.html#the-task-base-class-no-longer-automatically-register-tasks顯式說:「最好的做法是使用自定義任務類只用於覆蓋一般行爲,然後使用任務裝飾來實現任務」

至於結果,我得到了一個N​​otRegistered例外由於這種https://github.com/celery/celery/issues/3548,但加入app.tasks.register(CalculationWorker())沒解決不了。 我正在使用Django 1.10.X和芹菜4.0.0

這種方法仍然有效嗎?

感謝

回答

2

我不知道這是否是最好的解決辦法,但你可以用一種變通方法來得到你想要的行爲。我正在做類似的事情,以便我可以更清晰地將錯誤處理程序粘貼到任務上。

從文檔1

最好的做法是使用自定義任務類只用於覆蓋 一般行爲,然後使用任務裝飾實現 任務:

@app.task(bind=True, base=CustomTask) 
def custom(self): 
    print('running') 

但是,您可以將所有任務代碼放入CustomTask中,並在裝飾的任務聲明中留下存根。你必須打電話到你的任務的超存根像這樣:

@app.task(bin=True, base=CustomTask) 
def custom(self, *args): 
    super(type(self), self).run(*args) 

然後您把裝飾函數聲明的方式來調用到芹菜的任務註冊機械。不過,我希望5.0版本中有更清潔的東西。

4

如果使用芹菜-4.0.1,那麼你應該檢查文檔是chris 1指出docs

Task類不再使用特殊的元級,在任務註冊表自動註冊任務。

現在你應該註冊你的任務是這樣

class CustomTask(Task): 
    def run(self): 
     print('running') 
app.register_task(CustomTask())