Odoo Commit 每日一读/6 - 763d71

今天我们来看下odoo10关于定时任务的一个commit - 763d71.

改进内容

ir_cron.py中的_process_jobs方法新增了逻辑判断,当模块处于更新,安装,或者删除状态时,不进行自动任务的运行。

代码分析

        db = odoo.sql_db.db_connect(db_name)
        threading.current_thread().dbname = db_name
        try:
            with db.cursor() as cr:
                # Make sure the database has the same version as the code of
                # base and that no module must be installed/upgraded/removed
                cr.execute("SELECT latest_version FROM ir_module_module WHERE name=%s", ['base'])
                (version,) = cr.fetchone()
                cr.execute("SELECT COUNT(*) FROM ir_module_module WHERE state LIKE %s", ['to %'])
                (changes,) = cr.fetchone()
                if not version or changes:
                    raise BadModuleState()
                elif version != BASE_VERSION:
                    raise BadVersion()
                # Careful to compare timestamps with 'UTC' - everything is UTC as of v6.1.
                cr.execute("""SELECT * FROM ir_cron
                              WHERE numbercall != 0
                                  AND active AND nextcall <= (now() at time zone 'UTC')
                              ORDER BY priority""")
                jobs = cr.dictfetchall()

注意到with上下文中的开头两句查询语句。

  • 查询1:拉取定时任务中的关联模型的最新版本号。

  • 查询2: 统计数据库中模块的状态以 to开头的数据行数.

  • 接下来的逻辑判断也很容易理解

  • 若查询2返回结果大于0.则表示有模块正在更新或者安装。日志记录模块的状态。

  • 若查询1结果与BASE_VERSION 不同,日志记录版本不符。注意BASE_VERSION是从模块的__manifest__.py中直接读取的

    BASE_VERSION = odoo.modules.load_information_from_description_file('base')['version']
    

原始提交信息

1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/odoo/addons/base/ir/ir_cron.py b/odoo/addons/base/ir/ir_cron.py
index 95f90b5..bb070e4 100644
--- a/odoo/addons/base/ir/ir_cron.py
+++ b/odoo/addons/base/ir/ir_cron.py
@@ -186,17 +186,23 @@ class ir_cron(models.Model):
         jobs = []
         try:
             with db.cursor() as cr:
-                # Make sure the database we poll has the same version as the code of base
-                cr.execute("SELECT 1 FROM ir_module_module WHERE name=%s AND latest_version=%s", ('base', BASE_VERSION))
-                if cr.fetchone():
+                # Make sure the database has the same version as the code of
+                # base and that no module must be installed/upgraded/removed
+                cr.execute("SELECT latest_version FROM ir_module_module WHERE name=%s", ['base'])
+                (version,) = cr.fetchone()
+                cr.execute("SELECT COUNT(*) FROM ir_module_module WHERE state LIKE %s", ['to %'])
+                (changes,) = cr.fetchone()
+                if not version or changes:
+                    _logger.warning('Skipping database %s because of modules to install/upgrade/remove.', db_name)
+                elif version != BASE_VERSION:
+                    _logger.warning('Skipping database %s as its base version is not %s.', db_name, BASE_VERSION)
+                else:
                     # Careful to compare timestamps with 'UTC' - everything is UTC as of v6.1.
                     cr.execute("""SELECT * FROM ir_cron
                                   WHERE numbercall != 0
                                       AND active AND nextcall <= (now() at time zone 'UTC')
                                   ORDER BY priority""")
                     jobs = cr.dictfetchall()
-                else:
-                    _logger.warning('Skipping database %s as its base version is not %s.', db_name, BASE_VERSION)
         except psycopg2.ProgrammingError, e:
             if e.pgcode == '42P01':
                 # Class 42 — Syntax Error or Access Rule Violation; 42P01: undefined_table