summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2014-10-29 18:28:07 +0100
committerChristophe Simonis <chs@odoo.com>2014-10-29 18:28:07 +0100
commitcc4fba6089d3a65bb014d2aa33601668fca6f0bb (patch)
treeac1e9c877529250bdd3f1ea16a2c184c7efcb969
parent82588faa71e8da27d886ce8402841dc4985b95ff (diff)
[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.
-rw-r--r--openerp/modules/registry.py26
-rw-r--r--openerp/tools/func.py10
2 files changed, 30 insertions, 6 deletions
diff --git a/openerp/modules/registry.py b/openerp/modules/registry.py
index 679fae0cfc2..34672c44a78 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 baeae0b1465..0a36166acee 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: