问题
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,
回答1:
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.
来源:https://stackoverflow.com/questions/13492603/celery-task-with-multiple-decorators-not-auto-registering-task-name