From 67dfdc6a992b60e471ec88cd03f42b7399ae3e45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 22 May 2014 23:36:00 +0200 Subject: [PATCH] Make global cache depends on explicit context keys This should prevent the invalidation of the cache when the context keys that are changed has no influence onn the global cache. issue3905 review6291002 --- CHANGELOG | 2 ++ trytond/backend/database.py | 22 ++++++---------------- trytond/ir/lang.py | 3 +++ trytond/model/modelsql.py | 2 +- trytond/model/modelstorage.py | 4 ++-- 5 files changed, 14 insertions(+), 19 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index cec650bd5c..8ac0fe9aa5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +* Make global cache depends on explicit context keys +* Don't add to global cache Binary fields * Add MachMixin * Remove context, current_date and time from record rule evaluation diff --git a/trytond/backend/database.py b/trytond/backend/database.py index 2979c66ed2..dae790850d 100644 --- a/trytond/backend/database.py +++ b/trytond/backend/database.py @@ -105,29 +105,19 @@ class CursorInterface(object): Define generic interface for database cursor ''' IN_MAX = 1000 + cache_keys = {'language', 'fuzzy_translation', '_datetime'} def __init__(self): self.cache = {} - def get_cache(self, context=None): - ''' - Return cache for the context - - :param context: the context - :return: the cache dictionary - ''' + def get_cache(self): from trytond.cache import LRUDict from trytond.transaction import Transaction user = Transaction().user - if context is None: - context = {} - cache_ctx = context.copy() - for i in ('_timestamp', '_delete', '_create_records', - '_delete_records'): - if i in cache_ctx: - del cache_ctx[i] - return self.cache.setdefault((user, repr(cache_ctx)), - LRUDict(MODEL_CACHE_SIZE)) + context = Transaction().context + keys = tuple(((key, context[key]) for key in sorted(self.cache_keys) + if key in context)) + return self.cache.setdefault((user, keys), LRUDict(MODEL_CACHE_SIZE)) def execute(self, sql, params=None): ''' diff --git a/trytond/ir/lang.py b/trytond/ir/lang.py index a841274d38..dd3ec91f90 100644 --- a/trytond/ir/lang.py +++ b/trytond/ir/lang.py @@ -9,11 +9,14 @@ from ..tools import safe_eval, datetime_strftime from ..transaction import Transaction from ..pool import Pool from .time_locale import TIME_LOCALE +from ..backend.database import CursorInterface warnings.filterwarnings('ignore', "", ImportWarning) from locale import CHAR_MAX warnings.resetwarnings() +CursorInterface.cache_keys.add('translate_name') + __all__ = [ 'Lang', ] diff --git a/trytond/model/modelsql.py b/trytond/model/modelsql.py index 58b7dc76e1..9a04abd8bd 100644 --- a/trytond/model/modelsql.py +++ b/trytond/model/modelsql.py @@ -1053,7 +1053,7 @@ class ModelSQL(ModelStorage): cursor.execute(*select) rows = cursor.dictfetchmany(cursor.IN_MAX) - cache = cursor.get_cache(transaction.context) + cache = cursor.get_cache() if cls.__name__ not in cache: cache[cls.__name__] = LRUDict(RECORD_CACHE_SIZE) delete_records = transaction.delete_records.setdefault(cls.__name__, diff --git a/trytond/model/modelstorage.py b/trytond/model/modelstorage.py index 6bb5753993..8bb0b06037 100644 --- a/trytond/model/modelstorage.py +++ b/trytond/model/modelstorage.py @@ -1137,7 +1137,7 @@ class ModelStorage(Model): else: self._ids = [id] - self._cursor_cache = self._cursor.get_cache(self._context) + self._cursor_cache = self._cursor.get_cache() if _local_cache is not None: self._local_cache = _local_cache @@ -1300,7 +1300,7 @@ class ModelStorage(Model): if data['id'] == self.id and fname == name: value = fvalue if (field._type not in ('many2one', 'one2one', 'one2many', - 'many2many', 'reference') + 'many2many', 'reference', 'binary') and not isinstance(field, fields.Function)): continue if data['id'] not in self._local_cache: