[英]using class methods as celery tasks
I'm trying to use the methods of class as the django-celery tasks, marking it up using @task decorator.我正在尝试使用类的方法作为 django-celery 任务,使用 @task 装饰器对其进行标记。 The same situation is discribed here , asked by Anand Jeyahar. 此处描述了相同的情况,由 Anand Jeyahar 询问。 It's something like this是这样的
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
The problem is even if i use class instance like this a.foo.delay(bar)
it says, that foo
needs at least two arguments, which meens that self
pointer misses.问题是即使我使用这样的类实例a.foo.delay(bar)
它说, foo
至少需要两个参数,这意味着self
指针未命中。
More information:更多信息:
run()
method, using some argument as a key for method selection, but it's not exactly what i want.标记类与@task装饰任务,使类任务本身,它可能是能够执行从方法run()
方法,使用一些参数为方法选择的关键,但它不正是我想要的。self
argument to methods changes the way i execute the methods not as celery taks, but as usual methods (ie while testing)创建类的实例并将其作为self
参数传递给方法改变了我执行方法的方式,而不是像 celery taks 那样,而是像通常的方法一样(即在测试时)Thanks for your help!谢谢你的帮助!
Celery has experimental support for using methods as tasks since version 3.0. Celery 从 3.0 版本开始对使用方法作为任务提供实验支持。
The documentation for this is in celery.contrib.methods
, and also mentions some caveats you should be aware of:这方面的文档在celery.contrib.methods
,并且还提到了一些您应该注意的警告:
https://docs.celeryproject.org/en/3.1/reference/celery.contrib.methods.html https://docs.celeryproject.org/en/3.1/reference/celery.contrib.methods.html
Be aware : support for contrib.methods
removed from Celery since 4.0请注意:自 4.0 以来,对contrib.methods
支持已从 Celery 中移除
Jeremy Satterfield has a clean and straight forward tutorial to write class based tasks if that's what you want to accomplish. Jeremy Satterfield 有一个干净而直接的教程来编写基于类的任务,如果这是你想要完成的。 You can check it here .你可以在这里查看。
The magic is basically extending celery.Task
class including a run()
method, like something like this:魔法基本上是扩展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)
and then run the task like this:然后像这样运行任务:
your_arg = 3
custom_task = CustomTask()
custom_task.delay(your_arg)
I am not sure if ignore_result = True
part is necessary or not.我不确定ignore_result = True
部分是否必要。
When you have:当你有:
a = A()
you can do:你可以做:
A.foo.delay(a, param0, .., paramN)
Cheers干杯
For me the only one that works is celery.current_app because just this passes self
to the method.对我来说,唯一有效的方法是 celery.current_app,因为这将self
传递给方法。
So this should look like this:所以这应该是这样的:
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):
...
The name must be used if you have method with the same name in different classes.如果您在不同的类中具有相同名称的方法,则必须使用该名称。
I ran into a similar situation and decided to wrap class methods within a simple function that would redirect its parameters to an instance of the class and it's execution of such methods:我遇到了类似的情况,并决定将类方法包装在一个简单的函数中,该函数会将其参数重定向到类的实例,并执行此类方法:
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.