Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Celery task with multiple decorators not auto registering task name

I'm having a task that looks like this

from mybasetask_module import MyBaseTask

@task(base=MyBaseTask)
@my_custom_decorator 
def my_task(*args, **kwargs):
    pass

and my base task looks like this

from celery import task, Task

class MyBaseTask(Task):
    abstract = True
    default_retry_delay = 10 
    max_retries = 3 
    acks_late = True

The problem I'm running into is that the celery worker is registering the task with the name

'mybasetask_module.__inner'

The task is registerd fine (which is the package+module+function) when I remove @my_custom_decorator from the task or if I provide an explicit name to the task like this

from mybasetask_module import MyBaseTask

@task(base=MyBaseTask, name='an_explicit_task_name')
@my_custom_decorator 
def my_task(*args, **kwargs):
    pass

Is this behavior expected? Do I need to do something so that my tasks are registered with the default auto registered name in the first case when I have multiple decorators but no explicit task name?

Thanks,

like image 622
ksrini Avatar asked Nov 21 '12 11:11

ksrini


Video Answer


1 Answers

Use the functools.wraps() decorator to ensure that the wrapper returned by my_custom_decorator has the correct name:

from functools import wraps

def my_custom_decorator(func):
    @wraps(func)
    def __inner():
        return func()
    return __inner

The task name is taken from the function call that the task decorator wraps, but by inserting a decorator in between, you gave task your __inner wrapping function instead. The functools.wraps() decorator copies all the necessary metadata over from func to the wrapper so that task() can pick up the proper name.

like image 84
Martijn Pieters Avatar answered Sep 19 '22 21:09

Martijn Pieters



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!