我正在尝试使用class的方法作为django-celery任务,使用@task装饰器进行标记。 Anand Jeyahar问道,同样的情况被here所描述。 就像这样
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
指针未命中。
更多信息:
run()
方法执行方法,使用一些参数作为键方法选择,但它并不完全是我想要的。self
参数传递给方法会改变我执行方法而不是作为celery taks的方式,而是像通常的方法(即测试时)感谢您的帮助!
答案 0 :(得分:47)
自3.0版以来,Celery一直支持将方法用作任务。
此文档位于celery.contrib.methods
,并且还提到了一些您应该注意的警告:
http://docs.celeryproject.org/en/latest/reference/celery.contrib.methods.html
请注意:支持自{4.0}已从Celery 中移除
答案 1 :(得分:7)
Jeremy Satterfield有一个干净而直接的教程来编写基于类的任务,如果这是你想要完成的。您可以查看here。
魔术基本上是扩展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
部分是否必要BTW。
答案 2 :(得分:4)
当你有:
a = A()
你可以这样做:
A.foo.delay(a, param0, .., paramN)
干杯
答案 3 :(得分:1)
对我来说唯一有效的是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):
...
如果在不同的类中使用相同名称的方法,则必须使用该名称。
答案 4 :(得分:0)
我遇到了类似的情况,决定将类方法包装在一个简单的函数中,该函数将其参数重定向到该类的实例及其执行方法:
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)