[IMP] base: reduced number of checks on module loading
If you have a module with several dependencies or a complex dependency graph, the system repeats the number of checks of a module. For example: we have 4 modules A, B, C and D, where A depends on B and C, B depends on D and C depends on D. Before this patch, we check once if A is installed, once if B is installed, once if C is installed and twice id D is installed. With this patch, D is checked only once. On this example, the difference is minimal but on worse scenario as explained on the below issue, the processing time was provoking a timeout on test platform https://github.com/odoo/odoo/pull/29779#issuecomment-452821082 Cherry-pick to master of #29779 closes odoo/odoo#35185 Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
This commit is contained in:
committed by
Martin Trigaux
parent
a6f66f8bcf
commit
2486259ef9
@@ -338,35 +338,38 @@ class Module(models.Model):
|
||||
msg = _('Unable to process module "%s" because an external dependency is not met: %s')
|
||||
raise UserError(msg % (module_name, e.args[0]))
|
||||
|
||||
def _state_update(self, newstate, states_to_update, level=100):
|
||||
def _state_update(self, newstate, states_to_update, level=100, checked=False):
|
||||
if level < 1:
|
||||
raise UserError(_('Recursion error in modules dependencies !'))
|
||||
|
||||
# whether some modules are installed with demo data
|
||||
demo = False
|
||||
|
||||
for module in self:
|
||||
if not checked:
|
||||
checked = self.browse()
|
||||
for module in (self - checked):
|
||||
# determine dependency modules to update/others
|
||||
update_mods, ready_mods = self.browse(), self.browse()
|
||||
for dep in module.dependencies_id:
|
||||
if dep.state == 'unknown':
|
||||
raise UserError(_("You try to install module '%s' that depends on module '%s'.\nBut the latter module is not available in your system.") % (module.name, dep.name,))
|
||||
if dep.depend_id.state == newstate:
|
||||
ready_mods += dep.depend_id
|
||||
ready_mods |= dep.depend_id
|
||||
else:
|
||||
update_mods += dep.depend_id
|
||||
update_mods |= dep.depend_id
|
||||
|
||||
# update dependency modules that require it, and determine demo for module
|
||||
update_demo = update_mods._state_update(newstate, states_to_update, level=level-1)
|
||||
update_demo, now_checked = update_mods._state_update(
|
||||
newstate, states_to_update, level=level-1, checked=checked)
|
||||
module_demo = module.demo or update_demo or any(mod.demo for mod in ready_mods)
|
||||
demo = demo or module_demo
|
||||
checked |= now_checked
|
||||
|
||||
# check dependencies and update module itself
|
||||
self.check_external_dependencies(module.name, newstate)
|
||||
if module.state in states_to_update:
|
||||
module.write({'state': newstate, 'demo': module_demo})
|
||||
|
||||
return demo
|
||||
return demo, checked | self
|
||||
|
||||
@assert_log_admin_access
|
||||
def button_install(self):
|
||||
|
||||
Reference in New Issue
Block a user