具有多个装饰器的Celery任务不会自动注册任务名称

时间:2012-11-21 11:47:52

标签: python celery decorator django-celery python-decorators

我的任务看起来像这样

from mybasetask_module import MyBaseTask

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

我的基本任务看起来像这样

from celery import task, Task

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

我遇到的问题是芹菜工作者正在使用名称

注册任务
'mybasetask_module.__inner'

当我从任务中删除@my_custom_decorator或者我为这个任务提供一个明确的名称时,该任务被正确注册(这是包+模块+函数)

from mybasetask_module import MyBaseTask

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

预计会出现这种情况吗?我是否需要做一些事情,以便在我有多个装饰器但没有明确的任务名称时,在第一种情况下使用默认的自动注册名称注册我的任务?

谢谢,

1 个答案:

答案 0 :(得分:26)

使用functools.wraps() decorator确保my_custom_decorator返回的包装器具有正确的名称:

from functools import wraps

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

任务名称取自task装饰器包装的函数调用,但是通过在其间插入装饰器,您提供了task包裹函数__innerfunctools.wraps()装饰器将所有必要的元数据从func复制到包装器,以便task()可以获取正确的名称。