使用类方法作为芹菜任务

evi*_*nan 42 python django-celery

我正在尝试使用class的方法作为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
Run Code Online (Sandbox Code Playgroud)

问题是,即使我使用这样的类实例a.foo.delay(bar),它foo至少需要两个参数,这些self指针错过了指针.

更多信息:

  • 由于继承,我无法将类转换为模块
  • 方法强烈依赖于类成员,所以我不能使它们成为静态的
  • 标记与@task装饰任务,使一类任务本身,它可能是可以从执行该方法的run()方法,利用一些参数作为方法选择的关键,但它不正是我想要的.
  • 创建类的实例并将其作为self参数传递给方法会改变我执行方法的方式,而不是像celery taks那样,而是像通常的方法一样(即测试时)
  • 我试图找出如何在构造函数中以dinamically方式注册任务,但芹菜在工作者之间共享代码,这就是为什么它似乎是不可能的.

谢谢你的帮助!

ask*_*sol 49

从版本3.0开始,Celery对使用方法作为任务提供了实验支持.

这方面的文档在celery.contrib.methods,并提到了一些你应该注意的警告:

http://docs.celeryproject.org/en/latest/reference/celery.contrib.methods.html

请注意:自4.0以来支持contrib.methods从Celery中删除

  • 请注意:这似乎在2014年10月被删除,因为它太麻烦而无用 - https://github.com/celery/celery/commit/4f43276c236bbef7239a49b93815f478aec1d9f6 (9认同)

Gok*_*ari 8

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)
Run Code Online (Sandbox Code Playgroud)

然后像这样运行任务:

your_arg = 3

custom_task = CustomTask()
custom_task.delay(your_arg)
Run Code Online (Sandbox Code Playgroud)

我不确定是否ignore_result = True有必要BTW.


mih*_*icc 5

当你有:

    a = A()
Run Code Online (Sandbox Code Playgroud)

你可以做:

    A.foo.delay(a, param0, .., paramN)
Run Code Online (Sandbox Code Playgroud)

干杯