繁体   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