简体   繁体   English

为Django项目中的可重用应用程序创建基于类的Celery任务

[英]Create class based Celery task for reusable app in Django project

Creating function based task is quite clean for Django project. 对于Django项目,创建基于函数的任务非常干净。 Just create tasks.py in django app and start writing task like this example which is taken from official celery documentation at http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html 只需在Django应用中创建task.py并开始编写此示例,就可以从http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html的官方celery文档中获取此示例

from __future__ import absolute_import, unicode_literals
from celery import shared_task

@shared_task
def add(x, y):
    return x + y


@shared_task
def mul(x, y):
    return x * y

But sometimes function based tasks are tightly coupled and not very reusable. 但是有时基于功能的任务紧密结合在一起,并且不太可重用。 So i wanted to create class based celery task which is documented in official site. 所以我想创建基于类的芹菜任务,该任务已在官方网站上进行了记录。 After following https://github.com/celery/celery/issues/3874 I could create sample task but I am not sure if its proper way to create class based task. 在遵循https://github.com/celery/celery/issues/3874之后,我可以创建示例任务,但是我不确定它是否是创建基于类的任务的正确方法。

from __future__ import absolute_import, unicode_literals
from celery import shared_task, Task
import time
from celery import current_app


@shared_task
def add(x, y):
    time.sleep(5)
    return x + y


@shared_task
def mul(x, y):
    return x * y

# Sample class based task for testing
class AnotherTask(current_app.Task):
    name = 'tasks.another_task'
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def run(self):
        time.sleep(5)
        return self.x + self.y
# We need to manually register this class based task    
current_app.tasks.register(AnotherTask(3, 4))

I am able to call this task but each call result value is same 我可以调用此任务,但每个调用结果值都相同

(workflow) alok@alok-MacBookAir:~/exp/expdjango/mysite$ ./manage.py shell
Python 3.6.3 (default, Oct  3 2017, 21:45:48) 
Type "copyright", "credits" or "license" for more information.

IPython 5.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: from polls.tasks import *

In [2]: r = AnotherTask(3,4).delay()

In [3]: r.get()
Out[3]: 7

In [4]: r = AnotherTask(5,6).delay()

In [5]: r.get()
Out[5]: 7

Is it a proper way to create and call class based task? 这是创建和调用基于类的任务的正确方法吗?

Class based tasks are actually instantiated only once per runtime. 实际上,每个运行时仅实例化一次基于类的任务。 If you want your task to be parametrized, add arguments to the run method: 如果要对任务进行参数化,请向run方法添加参数:

class AnotherTask(current_app.Task):
    name = 'tasks.another_task'

    def run(self, x, y):
        time.sleep(5)
        return x + y

Then you can call it like: 然后您可以这样称呼它:

r = AnotherTask().delay(3, 4)
# Or
r = AnotherTask().apply_async(args=[3, 4])

This is also described in the docs on class based tasks , and in particular in the instantiation section . 基于类的任务的文档中,尤其是在实例化部分中 ,也对此进行了描述。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM