开发者

Django - Celery: @transaction and @task don't stack

I want to run a Django - Celery task with manual transaction management, but it seems that the annotations do not stack.

e.g.

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

@ta开发者_Go百科sk(ignore_result=True)
@transaction.commit_manually()
def pong(arg):
    print 'pong: %s' % arg
    transaction.rollback()

results in

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

while the reverse annotation order results in

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

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

It makes sense, but I'm having trouble finding a nice workaround. The Django docs don't mention alternatives to the annotation, and I don't want to make a class for each celery Task when I don't need one.

Any ideas?


Previously Celery had some magic where a set of default keyword arguments were passed to the task if it accepted them.

Since version 2.2 you can disable this behaviour, but the easiest is to import the task decorator from celery.task instead of celery.decorators:

from celery.task import task

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

The decorators module is deprecated and will be completely removed in 3.0, and the same for the "magic keyword arguments"

Note: For custom Task classes you should set the accept_magic_kwargs attribute to False:

class MyTask(Task):
    accept_magic_kwargs = False

Note2: Make sure your custom decorators preserves the name of the function using functools.wraps, otherwise the task will end up with the wrong name.


The task decorator generates a class x(Task) from your function with the run method as your target. Suggest you define the class and decorate the method.

Untested e.g.:

class pong(Task):
  ignore_result = True

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜