簡體   English   中英

使用類方法作為芹菜任務

[英]using class methods as celery tasks

我正在嘗試使用類的方法作為 django-celery 任務,使用 @task 裝飾器對其進行標記。 此處描述了相同的情況,由 Anand Jeyahar 詢問。 是這樣的

class A:
    @task
    def foo(self, bar):
        ...

def main():
    a = A()
    ...
    # what i need
    a.foo.delay(bar) # executes as celery task 
    a.foo(bar) # executes locally

問題是即使我使用這樣的類實例a.foo.delay(bar)它說, foo至少需要兩個參數,這意味着self指針未命中。

更多信息:

  • 由於繼承,我無法將類轉換為模塊
  • 方法強烈依賴於類成員,所以我不能將它們設為靜態
  • 標記與@task裝飾任務,使類任務本身,它可能是能夠執行從方法run()方法,使用一些參數為方法選擇的關鍵,但它不正是我想要的。
  • 創建類的實例並將其作為self參數傳遞給方法改變了我執行方法的方式,而不是像 celery taks 那樣,而是像通常的方法一樣(即在測試時)
  • 我試圖找出如何以動態方式注冊任務,例如從構造函數,但芹菜在工人之間共享代碼,所以這似乎是不可能的。

謝謝你的幫助!

Celery 從 3.0 版本開始對使用方法作為任務提供實驗支持。

這方面的文檔在celery.contrib.methods ,並且還提到了一些您應該注意的警告:

https://docs.celeryproject.org/en/3.1/reference/celery.contrib.methods.html

請注意自 4.0 以來,contrib.methods支持已從 Celery 中移除

Jeremy Satterfield 有一個干凈而直接的教程來編寫基於類的任務,如果這是你想要完成的。 你可以在這里查看

魔法基本上是擴展celery.Task類,包括一個run()方法,就像這樣:

from celery import Task

class CustomTask(Task):
    ignore_result = True

    def __init__(self, arg):
        self.arg = arg

    def run(self):
        do_something_with_arg(self.arg)

然后像這樣運行任務:

your_arg = 3

custom_task = CustomTask()
custom_task.delay(your_arg)

我不確定ignore_result = True部分是否必要。

當你有:

    a = A()

你可以做:

    A.foo.delay(a, param0, .., paramN)

干杯

對我來說,唯一有效的方法是 celery.current_app,因為這將self傳遞給方法。

所以這應該是這樣的:

from celery import current_app
from celery.contrib.methods import task_method

class A:
@current_app.task(filter=task_method, name='A.foo')
def foo(self, bar):
    ...

如果您在不同的類中具有相同名稱的方法,則必須使用該名稱。

我遇到了類似的情況,並決定將類方法包裝在一個簡單的函數中,該函數會將其參數重定向到類的實例,並執行此類方法:

class A:
    def foo(self, bar):
       # do this

a = A()

@app.task
def a_wrapper(bar):
    return a.foo(bar)

# probably in a different size with an import in-place:

a_wrapper.delay(bar)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM