Джанго - Сельдерей: @transaction и @task не складываются - PullRequest
5 голосов
/ 08 сентября 2011

Я хочу запустить задачу Django-Celery с ручным управлением транзакциями, но похоже, что аннотации не складываются.

например,

def ping():
    print 'ping'
    pong.delay('arg')

@task(ignore_result=True)
@transaction.commit_manually()
def pong(arg):
    print 'pong: %s' % arg
    transaction.rollback()

приводит к

TypeError: pong() got an unexpected keyword argument 'task_name'

, тогда как обратный порядок аннотаций дает

---> 22     pong.delay('arg')

AttributeError: 'function' object has no attribute 'delay'

Это имеет смысл, но яУ меня проблемы с поиском хорошего обходного пути.В документах Django не упоминаются альтернативы аннотации, и я не хочу создавать класс для каждой задачи сельдерея, когда она мне не нужна.

Есть идеи?

Ответы [ 2 ]

8 голосов
/ 09 сентября 2011

Ранее у Celery была какая-то магия, когда набор заданных по умолчанию аргументов ключевых слов передавался задаче, если она их принимала.

Начиная с версии 2.2 вы можете отключить это поведение, но проще всего импортировать taskдекоратор из celery.task вместо celery.decorators:

from celery.task import task

@task
@transaction.commit_manually
def t():
    pass

Модуль decorators устарел и будет полностью удален в 3.0, то же самое для "аргументов магического ключевого слова"

Примечание. Для пользовательских классов задач вы должны установить для атрибута accept_magic_kwargs значение False:

class MyTask(Task):
    accept_magic_kwargs = False

Примечание 2. Убедитесь, что ваши пользовательские декораторы сохраняют имя функции, используя functools.wraps, в противном случае задача завершитсяс неправильным именем.

6 голосов
/ 08 сентября 2011

Декоратор задачи генерирует class x(Task) из вашей функции с методом run в качестве вашей цели. Предложите вам определить класс и украсить метод.

Не проверено, например ::10000 *

class pong(Task):
  ignore_result = True

  @transaction.commit_manually()
  def run(self,arg,**kwargs):
    print 'pong: %s' % arg
    transaction.rollback()
...