Odoo啟動過程
\[本文基于odoo9源碼編寫\]
odoo包含的服務有
db
object
report
workflow
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命令帶的參數 判斷運行哪個命令, 命令可能是
deploy
scaffold
server
shell
start
如果不給出 command,則使用 默認,即server.
啟動前準備工作
檢查odoo用戶,不可以是 root
實例化配置文件
檢查pg用戶,不可以是postgres
報告配置情況
檢查是否設置 preload database,如果有,則創建空數據庫
創建 pid 文件
啟動 openerp.service.server
openerp.service.server啟動過程
定義全局變量 server
裝載 全服務器模塊 load\_server\_wide\_modules\(\),默認是 web 和 web\_kanban,可以通過 server\_wide\_modules 配置項設置更多的 預裝載模塊。 運行 openerp.modules.module.load\_openerp\_module\(\) 裝載web 和web\_kanban 模塊。此時,僅僅將這些模塊當作 pyton 模塊處理,并不執行任何的 ORM過程
根據 configuration 調用對應的服務器,odoo支持3種模式
GeventServer
PreforkServer,會調用 geventServer 作為longpolling 的服務端
ThreadedServer
如果設置了 workers 參數, 則是 preforkserver,默認是 threadserver。然后根據配置 執行RegistryManager.new\(\) 裝載 preload 指定的數據庫以及指定的模塊; 如果沒有指定preload,則在 第一個用戶訪問該odoo數據庫時,裝載odoo模塊。 odoo實例為每個數據庫維護一個 registry,用來維護模塊注冊。使用RegistryManager 管理 registry,在 new\(\)時, 使用openerp.modules.load\_modules\(\)加載odoo模塊; 此時,不僅將odoo模塊作為Python模塊導入, 并執行ORM過程。
啟動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
步驟
初始化系統路徑
檢查數據庫是否初始化,否則 初始化數據庫,使用 openerp\addons\base\base.sql
初始化注冊表registry
加載base 模塊,初始化 模塊依賴圖 graph,將base 添加到 圖,執行 load\_module\_graph\(\) 裝載 base 模塊,在注冊表設置模型,裝載語言,標記其他需要裝載和升級的模塊。
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指令,驗證視圖, 裝載演示數據,更新注冊表。
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 】
數據持久化部分, 待更 【 挖坑 :) 】
執行 load\_marked\_modules\(\) 裝載 其他已安裝、或者要升級\/移除的模塊,此時會查詢 ir\_module\_module, 讀取需要執行 裝載動作的 模塊, 并加入到 depends graph 里面, 然后 再次 執行 load\_module\_graph\(\)
完成安裝并執行清理動作
其他步驟
轉載注明原作者 \/by Jeffery