介绍
Celery在使用时必须创造一个实例,也就是application,它是线程安全的,所以多个Celery application(不同的配置、部件和任务)都可以在一个进程空间中存在。
from celery import Celery
app = Celery()
app.main
<Celery __main__:0x100469fd0> # main module的名称 __main__
名称
当发送任务信息时,是不包含任何源代码的,只有一个任务名称,而每个工作进程都维持着一个任务名称到具体函数的映射(任务注册)。每个任务在创建时,是加在本地的,如果是在main函数中创建的,任务名称会以main起始。可以使用显示的方式指定任务名称前缀:
>>> @app.task
... def add(x, y):
... return x + y
>>> add
<@task: __main__.add>
>>> add.name
__main__.add
>>> app.tasks['__main__.add']
<@task: __main__.add>
以上的基本没什么用
app = Celery('tasks')
app.main
tasks
这样之后创建的task就会以tasks为前缀,tasks.add。
配置
配置以这样的顺序生效:
1、运行时的修改
2、配置模块
3、默认的配置
使用模块名称
app = Celery()
app.config_from_object('celeryconfig')
使用模块
import celeryconfig
app.config_from_object(celeryconfig)
使用配置类
class Config:
enable_utc = True
timezone = 'Europe/London'
app.config_from_object(Config)
使用环境变量
os.environ.setdefault('CELERY_CONFIG_MODULE', 'celeryconfig')
app.config_from_envvar('CELERY_CONFIG_MODULE')
使用humanize打印配置信息
app.conf.humanize(with_defaults=False, censored=True)
# 不打印默认的设置和敏感信息(如密码)
app.conf.table(with_defaults=False, censored=True)
# 返回一个包含配置文件的dict
敏感信息指包含这些字符串的:
API, TOKEN, KEY, SECRET, PASS, SIGNATURE, DATABASE
Laziness
app
app只有在需要的时候才实例化出来,创建一个celery实例只是:
创建一个逻辑时钟实例,用于events.
创建任务注册
设置自己为当前app(but not if the set_as_current argument was disabled)
调用app.on_init() (does nothing by default).
task
在task定义的地方并没有构造task,在使用的时候才创建,或者被finalized:
@app.task
def add(x, y):
return x + y
add.__evaluated__()
False
add # 调用add的repr
<@task: __main__.add>
add.__evaluated__()
True
finalize
Finalization 显式调用 app.finalize() 或 获取app.tasks的属性
复制需要在应用之间共享的任务
默认为共享的,如果设为不共享则任务是绑定它的app所私有的。
运行所有的task装饰器
确保所有的task绑定到当前app
这样task可以读取配置
抽象Tasks
@app.task(base=OtherTask):
def add(x, y):
return x + y
from celery import Task
class DebugTask(Task):
def __call__(self, *args, **kwargs):
print('TASK STARTING: {0.name}[{0.request.id}]'.format(self))
return super(DebugTask, self).__call__(*args, **kwargs)