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')
@task(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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With