diff --git a/odoo/addons/base/models/ir_http.py b/odoo/addons/base/models/ir_http.py index 1dbb94cca5b..3eba7932a44 100644 --- a/odoo/addons/base/models/ir_http.py +++ b/odoo/addons/base/models/ir_http.py @@ -79,6 +79,42 @@ class SignedIntConverter(NumberConverter): num_convert = int +class LazyCompiledBuilder: + def __init__(self, rule, _compile_builder, append_unknown): + self.rule = rule + self._callable = None + self._compile_builder = _compile_builder + self._append_unknown = append_unknown + + def __get__(self, *args): + # Rule.compile will actually call + # + # self._build = self._compile_builder(False).__get__(self, None) + # self._build_unknown = self._compile_builder(True).__get__(self, None) + # + # meaning the _build and _build unkown will contain _compile_builder().__get__(self, None). + # This is why this override of __get__ is needed. + return self + + def __call__(self, *args, **kwargs): + if self._callable is None: + self._callable = self._compile_builder(self._append_unknown).__get__(self.rule, None) + del self.rule + del self._compile_builder + del self._append_unknown + return self._callable(*args, **kwargs) + + +class FasterRule(werkzeug.routing.Rule): + """ + _compile_builder is a major part of the routing map generation and rules + are actually not build so often. + This classe makes calls to _compile_builder lazy + """ + def _compile_builder(self, append_unknown=True): + return LazyCompiledBuilder(self, super()._compile_builder, append_unknown) + + class IrHttp(models.AbstractModel): _name = 'ir.http' _description = "HTTP Routing" @@ -206,7 +242,7 @@ class IrHttp(models.AbstractModel): routing = submap(endpoint.routing, ROUTING_KEYS) if routing['methods'] is not None and 'OPTIONS' not in routing['methods']: routing['methods'] = routing['methods'] + ['OPTIONS'] - rule = werkzeug.routing.Rule(url, endpoint=endpoint, **routing) + rule = FasterRule(url, endpoint=endpoint, **routing) rule.merge_slashes = False routing_map.add(rule) cls._routing_map[key] = routing_map