From cc4fba6089d3a65bb014d2aa33601668fca6f0bb Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Wed, 29 Oct 2014 18:28:07 +0100 Subject: [PATCH] [IMP] core: manage registries via an LRU. When working with a large number of databases, the memory allocated to registries wasn't limited, resulting to waste memory (especially in the longpolling worker, which is not recycled). The size of the LRU is depending on the soft limit configured for workers. --- openerp/modules/registry.py | 26 +++++++++++++++++++++----- openerp/tools/func.py | 10 +++++++++- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/openerp/modules/registry.py b/openerp/modules/registry.py index 679fae0..34672c4 100644 --- a/openerp/modules/registry.py +++ b/openerp/modules/registry.py @@ -23,13 +23,14 @@ """ from collections import Mapping -from contextlib import contextmanager import logging +import os import threading import openerp from .. import SUPERUSER_ID -from openerp.tools import assertion_report, lazy_property +from openerp.tools import assertion_report, lazy_property, classproperty, config +from openerp.tools.lru import LRU _logger = logging.getLogger(__name__) @@ -259,12 +260,27 @@ class RegistryManager(object): registries (essentially database connection/model registry pairs). """ - # Mapping between db name and model registry. - # Accessed through the methods below. - registries = {} + _registries = None _lock = threading.RLock() _saved_lock = None + @classproperty + def registries(cls): + if cls._registries is None: + size = config.get('registry_lru_size', None) + if not size: + # Size the LRU depending of the memory limits + if os.name != 'posix': + # cannot specify the memory limit soft on windows... + size = 42 + else: + # On average, a clean registry take 25MB of memory + cache + avgsz = 30 * 1024 * 1024 + size = int(config['limit_memory_soft'] / avgsz) + + cls._registries = LRU(size) + return cls._registries + @classmethod def lock(cls): """ Return the current registry lock. """ diff --git a/openerp/tools/func.py b/openerp/tools/func.py index baeae0b..0a36166 100644 --- a/openerp/tools/func.py +++ b/openerp/tools/func.py @@ -20,7 +20,7 @@ # ############################################################################## -__all__ = ['synchronized', 'lazy_property'] +__all__ = ['synchronized', 'lazy_property', 'classproperty'] from functools import wraps from inspect import getsourcefile @@ -103,4 +103,12 @@ def compose(a, b): return a(b(*args, **kwargs)) return wrapper + +class _ClassProperty(property): + def __get__(self, cls, owner): + return self.fget.__get__(None, owner)() + +def classproperty(func): + return _ClassProperty(classmethod(func)) + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: -- 1.7.10.4