1. 程式人生 > >16.odoo入門——初探後臺啟動過程(三)

16.odoo入門——初探後臺啟動過程(三)

第16天——終於週五,迎來難得的雙休

上次說到,執行如下程式碼:

 rc = odoo.service.server.start(preload=preload, stop=stop)#————又呼叫了odoo/service/server.py下的start函式啦  
去到odoo10/odoo/service/server.py下檢視定義的一個全域性函式:
def start(preload=None, stop=False):
    """ Start the odoo http server and cron processor.
    """
    global server  #使用全域性變數 server
    load_server_wide_modules() #載入openerp的一些模組
    if odoo.evented:
        server = GeventServer(odoo.service.wsgi_server.application)
    elif config['workers']:
        server = PreforkServer(odoo.service.wsgi_server.application)
    else:
        server = ThreadedServer(odoo.service.wsgi_server.application)

    watcher = None
    if 'reload' in config['dev_mode']:
        if watchdog:
            watcher = FSWatcher()
            watcher.start()
        else:
            _logger.warning("'watchdog' module not installed. Code autoreload feature is disabled”)
    if 'werkzeug' in config['dev_mode']:
		
        server.app = DebuggedApplication(server.app, evalex=True)

    rc = server.run(preload, stop)

    # like the legend of the phoenix, all ends with beginnings
    if getattr(odoo, 'phoenix', False):
        if watcher:
            watcher.stop()
        _reexec()

    return rc if rc else 0

這樣吧,我們按照函式執行流程,從上往下依次進行分析,

global server  #使用了全域性變數server.

在該檔案上下文中可以看到,server = None , 是一個空物件

接下來呼叫該檔案中的一個全域性函式:load_server_wide_modules

其函式原始碼為:

def load_server_wide_modules():
    for m in odoo.conf.server_wide_modules:
        try:
            odoo.modules.module.load_openerp_module(m)
        except Exception:
            msg = ''
            if m == 'web':
                msg = """
The `web` module is provided by the addons found in the `openerp-web` project.
Maybe you forgot to add those addons in your addons_path configuration."""
            _logger.exception('Failed to load server-wide module `%s`.%s', m, msg)
通過嵌套了這個
print "in load_server_wide_modules  ",m
 這條測試語句,看到odoo.conf.server_wide_modules2個物件,分別為webweb_kanban

接下來運行了odoo.modules.module.load_openerp_module(m)函式,找到odoo/modules/module.py下的load_openerp_module函式,這是個全域性函式:

def load_openerp_module(module_name):
    """ Load an OpenERP module, if not already loaded.

    This loads the module and register all of its models, thanks to either
    the MetaModel metaclass, or the explicit instantiation of the model.
    This is also used to load server-wide module (i.e. it is also used
    when there is no model to register).
    """
    global loaded    #全域性變數loaded是一個列表,儲存著已經load的模組
    if module_name in loaded:  #如果已經載入就不用再載入了,直接return
        return

    initialize_sys_path() #初始化路徑
    try:
        __import__('odoo.addons.' + module_name)

        # Call the module's post-load hook. This can done before any model or
        # data has been initialized. This is ok as the post-load hook is for
        # server-wide (instead of registry-specific) functionalities.
        info = load_information_from_description_file(module_name)
        if info['post_load']:
            getattr(sys.modules['odoo.addons.' + module_name], info['post_load'])()

    except Exception, e:
        msg = "Couldn't load module %s" % (module_name)
        _logger.critical(msg)
        _logger.critical(e)
        raise
    else:
        loaded.append(module_name)

也就是說load_openerp_module 這個函式大概就是找找路徑,確認載入我們需要載入的模組。

接下來選擇伺服器模式,我們這裡是進入了 ThreadedServerThreadedServer是在odoo/service/server.py下宣告的一個類,主要用於管理執行緒

使用watcher,可以實現Code autoreload,不過在我現行使用中並沒有配置reload這個功能,因為可以發現我的odoo中的config[‘dev’]是空的。

進入

rc = server.run(preload, stop)
 語句———伺服器啟動囉。

接下來的幾條程式碼行都是有關伺服器退出的啦。下一次我們將觀察一下這個ThreadedServer是如何實現執行緒管理的吧!