内容简介:Celery在使用前必须实例化,称为application或app。app是线程安全的,具有不同配置、组件、task的多个Celery应用可以在同一个进程空间共存。最后一行文本化显示了Celery应用:包含应用所属类的名称,当前主模块名,以及内存地址。唯一重要的信息是模块名称。在Celery中发送task消息时,该消息仅包含要执行的task的名称。每一个worker维护一个task名称和对应函数的映射,这称为
Celery在使用前必须实例化,称为application或app。app是线程安全的,具有不同配置、组件、task的多个Celery应用可以在同一个进程空间共存。
# 创建Celery应用 >>> from celery import Celery >>> app = Celery() >>> app <Celery __main__:0x100469fd0>
最后一行文本化显示了Celery应用:包含应用所属类的名称,当前主模块名,以及内存地址。唯一重要的信息是模块名称。
Main Name
在Celery中发送task消息时,该消息仅包含要执行的task的名称。每一个worker维护一个task名称和对应函数的映射,这称为 task registry
。
当定义一个task时,该task将注册到本地:
>>> @app.task ... def add(x, y): ... return x + y >>> add <@task: __main__.add> >>> add.name __main__.add >>> app.tasks['__main__.add'] <@task: __main__.add>
当Celery无法检测task函数属于哪个模块时,使用main模块名生成初始task名称。
这种方式仅适用于以下两种场景:
- 定义task的模块作为程序运行
- app在python shell中创建
# tasks.py from celery import Celery app = Celery() @app.task def add(x, y): return x + y if __name__ == '__main__': app.worker_main()
如果直接运行tasks.py,task名将以 __main__
为前缀,但如果tasks.py被其他程序导入,task名将以 tasks
为前缀。如下:
>>> from tasks import add >>> add.name tasks.add
也可以直接指定主模块名:
>>> app = Celery('tasks') >>> app.main 'tasks' >>> @app.task ... def add(x, y): ... return x + y >>> add.name tasks.add
Configuration
可以通过直接设置,或使用专用配置模块对Celery进行配置。
通过 app.conf
属性查看或直接设置配置:
>>> app.conf.timezone 'Europe/London' >>> app.conf.enable_utc = True
或用 app.conf.update
方法一次更新多个配置:
>>> app.conf.update( ... enable_utc=True, ... timezone='Europe/London', ...)
config_from_object
app.config_from_object()
方法从配置模块或对象中导入配置。需要注意的是: 调用config_from_object()方法将重置在这之前配置的任何设置
。
使用模块名
app.config_from_object()方法接收 python 模块的完全限定名( fully qualified name
)或具体到其中的某个属性名,例如"celeryconfig", "myproj.config.celery", 或"myproj.config:CeleryConfig":
from celery import Celery app = Celery() app.config_from_object('celeryconfig')
只要能够正常执行 import celeryconfig
,app就能正常配置。
使用模块对象
也可以传入一个已导入的模块对象,但不建议这样做。
import celeryconfig from celery import Celery app = Celery() app.config_from_object(celeryconfig)
更推荐使用模块名的方式,因为这样在使用prefork pool时不需要序列化该模块。如果在实际应用中出现配置问题或序列化错误,请尝试使用模块名的方式。
使用配置类或对象
from celery import Celery app = Celery() class Config: enable_utc = True timezone = 'Europe/London' app.config_from_object(Config)
config_from_envvar
app.config_from_envvar()
方法从环境变量中接收配置模块名。
import os from celery import Celery #: Set default configuration module name os.environ.setdefault('CELERY_CONFIG_MODULE', 'celeryconfig') app = Celery() app.config_from_envvar('CELERY_CONFIG_MODULE')
通过环境变量指定配置模块:
$ CELERY_CONFIG_MODULE="celeryconfig.prod" celery worker -l info
Censored configuration
如果要显示Celery配置,可能需要过滤某些敏感信息如密码、密钥等。Celery提供了几种用于帮助显示配置的实用方法。
humanize()
该方法返回列表字符串形式的配置,默认只包含改动过的配置,如果要显示内置的默认配置,设置 with_defaults
参数为True:
>>> app.conf.humanize(with_defaults=False, censored=True)
table()
该方法返回字典形式的配置:
>>> app.conf.table(with_defaults=False, censored=True)
Celery可能不会移除所有的敏感信息,因为它使用正则表达式匹配键并判断是否移除。如果用户添加了包含敏感信息的自定义配置,可以使用Celery可能标记为敏感配置的名称来命名(API, TOKEN, KEY, SECRET, PASS, SIGNATURE, DATABASE)。
Laziness
应用实例是惰性的。
创建Celery实例只会执行以下操作:
logical clock instance task registry set_as_current app.on_init()
app.task()
装饰器不会在task定义时立即创建task,而是在task使用时或 finalized
应用后创建。
下例说明了在使用task或访问其属性前,都不会创建task:
>>> @app.task >>> def add(x, y): ... return x + y >>> type(add) <class 'celery.local.PromiseProxy'> >>> add.__evaluated__() False >>> add # <-- causes repr(add) to happen <@task: __main__.add> >>> add.__evaluated__() True
应用的 Finalization
指显式地调用 app.finalize()
方法或隐式地访问app.tasks属性。
finalized
应用将会:
shared
Breaking the chain
虽然可以依赖于当前应用,但最佳实践是将应用实例传递给任何需要它的对象,这个行为可以称为 app chain
。
# 依赖于当前应用(bad) from celery import current_app class Scheduler(object): def run(self): app = current_app
# 传递应用实例(good) class Scheduler(object): def __init__(self, app): self.app = app
在开发模式设置CELERY_TRACE_APP环境变量,可以在应用链断开时抛出异常:
$ CELERY_TRACE_APP=1 celery worker -l info
Abstract Tasks
使用 task()
装饰器创建的task都继承自 celery.app.task
模块的 Task
基类。继承该类可以自定义task类:
from celery import Task # 或者 from celery.app.task 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)
如果要重写 __call__()
方法,记得调用super。这样在task直接调用时会执行基类的默认事件。
Task
基类是特殊的,因为它并未绑定到任何特定的应用。一旦task绑定到应用,它将读取配置以设置默认值等。
-
通过
base
参数指定基类@app.task(base=DebugTask) def add(x, y): return x + y
-
通过
app.Task
属性指定基类>>> from celery import Celery, Task >>> app = Celery() >>> class MyBaseTask(Task): ... queue = 'hipri' >>> app.Task = MyBaseTask >>> app.Task <unbound MyBaseTask> >>> @app.task ... def add(x, y): ... return x + y >>> add <@task: __main__.add> >>> add.__class__.mro() [<class add of <Celery __main__:0x1012b4410>>, <unbound MyBaseTask>, <unbound Task>, <type 'object'>]
以上所述就是小编给大家介绍的《Celery中文翻译-Application》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 基于 Laravel、Lumen 框架集成百度翻译、有道翻译、Google 翻译扩展包
- 腾讯发布人工智能辅助翻译 致敬人工翻译
- golang调用baidu翻译api实现自动翻译
- 监管机器翻译质量?且看阿里如何搭建翻译质量评估模型
- 机器翻译新突破:谷歌实现完全基于attention的翻译架构
- PendingIntent 是个啥?官方文档描述的很到位。我给翻译翻译
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Realm of Racket
Matthias Felleisen、Conrad Barski M.D.、David Van Horn、Eight Students Northeastern University of / No Starch Press / 2013-6-25 / USD 39.95
Racket is the noble descendant of Lisp, a programming language renowned for its elegance and power. But while Racket retains the functional goodness of Lisp that makes programming purists drool, it wa......一起来看看 《Realm of Racket》 这本书的介绍吧!
SHA 加密
SHA 加密工具
HEX CMYK 转换工具
HEX CMYK 互转工具