子类化Celery Task为`ClassTask` mixin

时间:2014-01-15 23:51:25

标签: python celery celery-task

将我的问题写成我刚接触Celery的事实,这个(1)可能已在其他地方得到解答(如果是,我找不到答案)或(2)可能有更好的方法实现我的目标而不是我直接要求的目标。

另外,我知道celery.contrib.methods,但task_method并没有完全达到我想要的效果。

我的目标

我想创建一个类mixin,将整个类转换为Celery任务。例如,mixin由下面的代码表示(现在不运行):

from celery import Task

class ClassTaskMixin(Task):

    @classmethod
    def enqueue(cls, *args, **kwargs):
        cls.delay(*args, **kwargs)

    def run(self, *args, **kwargs):
        Obj = type(self.name, (), {})
        Obj(*args, **kwargs).run_now()

    def run_now(self):
        raise NotImplementedError()

与使用task_method时不同,我 not 想要在任务排队并调用.delay()之前完全实例化该类。相反,我想简单地将类名和任何相关的初始化参数一起移交给异步进程。然后,异步进程将使用类名和给定的初始化参数完全实例化该类,然后在实例化对象上调用某个方法(例如.run_now())。

示例用例

异步构造和发送电子邮件将是我需要的mixin的一个示例用途。

class WelcomeEmail(EmailBase, ClassTaskMixin):

    def __init__(self, recipient_address, template_name, template_context):
        self.recipient_address = recipient_address
        self.template_name = template_name
        self.template_context = template_context

   def send(self):
       self.render_templates()
       self.construct_mime()
       self.archive_to_db()
       self.send_smtp_email()

   def run_now(self):
       self.send()

上述代码将通过调用WelcomeEmail.enqueue(recipient_address, template_name, template_context)在异步Celery进程中发送电子邮件。在进程中同步发送电子邮件将通过调用WelcomeEmail(recipient_address, template_name, template_context).send()来完成。

问题

  1. 有什么理由说我在Celery框架内做的事情是非常非常错误的吗?
  2. 有没有更好的方法来构建mixin以使其比我提出的更多Celery-onic(更好的属性名称,不同的方法结构等)?
  3. 在我所描述的用例中,我缺少什么使mixin功能正常?

1 个答案:

答案 0 :(得分:2)

显然这个问题对很多人来说并不是很有趣,但是......我已经完成了我的目标。

有关详细信息,请参阅提取请求https://github.com/celery/celery/pull/1897