中菁- odoo  ERP 实施 杭州

示例图片三
首页 > Odoo资讯 > odoo知识库

Odoo启动过程

2017-03-20 15:34:34 中菁- odoo ERP 实施 杭州 阅读

[本文基于odoo9源码编写]

odoo包含的服务有

  1. db

  2. object

  3. report

  4. workflow

  5. web[wsgi]

Odoo以wsgi 规范提供Web及Web服务db/object/report,而workflow则包含在model里面,以create[delete|redirect|signal|step]_workflow() 提供服务。Odoo9之后为了保持兼容性,还是保持了旧模式,在 openerp/netsvc.py 定义为 LocalService,提供 workflow 和 report 服务

 

openerp/cli/main() 函数为odoo的入口,  定义在 openerp/cli/command.py,此函数根据cli命令带的参数 判断运行哪个命令, 命令可能是

  1. deploy

  2. scaffold

  3. server

  4. shell

  5. start

如果不给出 command,则使用 默认,即server.

 

启动前准备工作

  1. 检查odoo用户,不可以是 root

  2. 实例化配置文件

  3. 检查pg用户,不可以是postgres

  4. 报告配置情况

  5. 检查是否设置 preload database,如果有,则创建空数据库

  6. 创建 pid 文件

  7. 启动 openerp.service.server

 

openerp.service.server启动过程

  1. 定义全局变量 server

  2. 装载 全服务器模块 load_server_wide_modules(),默认是 web 和 web_kanban,可以通过 server_wide_modules 配置项设置更多的 预装载模块。 运行  openerp.modules.module.load_openerp_module() 装载web 和web_kanban 模块。此时,仅仅将这些模块当作 pyton 模块处理,并不执行任何的 ORM过程

  3. 根据 configuration 调用对应的服务器,odoo支持3种模式

    1. GeventServer

    2. PreforkServer,会调用 geventServer 作为longpolling  的服务端

    3. ThreadedServer

  4. 如果设置了 workers 参数, 则是 preforkserver,默认是 threadserver。然后根据配置 执行RegistryManager.new() 装载 preload 指定的数据库以及指定的模块; 如果没有指定preload,则在 第一个用户访问该odoo数据库时,装载odoo模块。 odoo实例为每个数据库维护一个 registry,用来维护模块注册。使用RegistryManager 管理 registry,在 new()时, 使用openerp.modules.load_modules()加载odoo模块; 此时,不仅将odoo模块作为Python模块导入, 并执行ORM过程。

  5. 启动wsgi 应用程序,调用 wsgi_xmlrpc() 和 openerp.http.root 这2个handler。 如果启动odoo时没有指定preload,则在第一次访问 wsgi root时,通过   ir_http = request.registry['ir.http']  尝试进行 odoo模块装载。

 

装载odoo模块以及ModelClass构建

 openerp.modules.load_modules()  定义在  py文件   openerp\modules\loading.py

步骤:

  1. 初始化系统路径

  2. 检查数据库是否初始化,否则 初始化数据库,使用  openerp\addons\base\base.sql

  3. 初始化注册表registry

  4. 加载base 模块,初始化 模块依赖图 graph,将base 添加到  图,执行    load_module_graph()   装载 base 模块,在注册表设置模型,装载语言,标记其他需要装载和升级的模块。

    1. load_module_graph() 过程如下, 初始化 注册表 和迁移管理器,执行pre 迁移脚本 ,以及odoo模块定义的 pre_init_hook指令,导入odoo模块,将模块里面定义的Model 更新 models.MetaModel.module_to_models[  ],使用  registry.load()  加载 odoo 模块,执行模块定义的 init 或者 update 指令,执行 post迁移脚本,更新翻译,更新注册表,执行odoo模块定义的 post_init_hook指令,验证视图, 装载演示数据,更新注册表。

    2. registry.load() 首先导入 models.py, 然后 遍历  models.MetaModel.module_to_models[  ]  登记的  python class,然后执行 models.BaseModel._build_model() 基于 python class 动态 建立 oodo model class, odoo model class 将 按照 graph 里面的依赖顺序,依次继承 python class 构建 odoo model class.  例如,  <class 'openerp.addons.stock.product.product_template'>   在 ORM 时, 将通过  继承关系遍历出 全部的 父类【inherit[s]】,再加上它自己 ,例如 <type 'list'>: [<class 'openerp.addons.stock.product.product_template'>, <class 'openerp.addons.sale.sale.ProductTemplate'>, <class 'openerp.addons.account.models.product.ProductTemplate'>, <class 'openerp.addons.product.product.product_template'>, <class 'openerp.addons.mail.models.mail_thread.MailThread'>], 然后 基于这些  基类, 使用  type()  构建出 odoo model class.    【<class 'openerp.api.product.template'>  】  和  odoo model 【 template: product.template 】

    3. 数据持久化部分

  5. 执行  load_marked_modules()  装载 其他已安装、或者要升级/移除的模块,此时会查询 ir_module_module, 读取需要执行 装载动作的 模块, 并加入到 depends graph 里面, 然后 再次 执行 load_module_graph() 

  6. 完成安装并执行清理动作

  7. 其他步骤


Powered by MetInfo 5.3.15 ©2008-2018 www.metinfo.cn