создание подкласса задачи Celery для миксина `ClassTask`

Предваряя мой вопрос тем фактом, что я новичок в Celery, и на это (1) мог быть дан ответ где-то еще (если это так, я не смог найти ответ) или (2) может быть лучший способ достичь моей цели чем то, о чем я прямо спрашиваю.

Кроме того, я знаю о celery.contrib.methods, но task_method не совсем соответствует тому, что я ищу.

Моя цель

Я хотел бы создать примесь класса, которая превращает весь класс в задачу Celery. Например, миксин, представленный чем-то вроде приведенного ниже кода (который сейчас не запускается):

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, я не хочу полностью создавать экземпляр класса до постановки задачи в очередь и вызова .delay(). Скорее, я хочу просто передать имя класса вместе с любыми соответствующими параметрами инициализации асинхронному процессу. Затем асинхронный процесс полностью создаст экземпляр класса, используя имя класса и заданные параметры инициализации, а затем вызовет какой-либо метод (например, .run_now()) для созданного объекта.

Пример использования

Создание и отправка электронной почты асинхронно может быть примером использования миксина, который мне нужен.

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()

Приведенный выше код отправляет электронное письмо в асинхронном процессе Celery, вызывая WelcomeEmail.enqueue(recipient_address, template_name, template_context). Синхронная отправка электронной почты в процессе может быть выполнена вызовом WelcomeEmail(recipient_address, template_name, template_context).send().

Вопросы

  1. Есть ли причина того, что то, что я пытаюсь сделать, очень, очень неправильно в рамках Celery?
  2. Есть ли лучший способ структурировать миксин, чтобы сделать его более сельдерейным, чем то, что я предложил (лучшие имена атрибутов, другая структура методов и т. д.)?
  3. Чего мне не хватает, чтобы примесь работала в случае использования, как я описал?

person kalefranz    schedule 15.01.2014    source источник


Ответы (1)


По-видимому, многим этот вопрос не очень интересен, но... Я добился того, что намеревался сделать.

См. запрос на вытягивание https://github.com/celery/celery/pull/1897 для Детали.

person kalefranz    schedule 07.03.2014