@@ -1,3 +1,4 @@
|
||||
* Add local and global list of ignore context keys
|
||||
* Add functions in transaction for check access and active record
|
||||
* Add check_access and active_records attribute to Transaction
|
||||
* Add searchable and sortable methods on Field
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Cache
|
||||
=====
|
||||
|
||||
.. class:: Cache(name[, size_limit[, duration[, context]]])
|
||||
.. class:: Cache(name[, size_limit[, duration[, context[, context_ignored_keys]]]])
|
||||
|
||||
Use to cache values between server requests.
|
||||
|
||||
@@ -19,6 +19,7 @@ Cache
|
||||
|
||||
And the ``context`` parameter is used to indicate if the cache depends on
|
||||
the user context and is ``True`` by default.
|
||||
Keys specified in ``context_ignored_keys`` are ignored.
|
||||
|
||||
The cache is cleaned on :class:`~trytond.transaction.Transaction` starts and
|
||||
resets on :class:`~trytond.transaction.Transaction` commit or rollback.
|
||||
|
||||
@@ -64,11 +64,23 @@ def _get_modules(cursor):
|
||||
|
||||
class BaseCache(object):
|
||||
_instances = {}
|
||||
context_ignored_keys = {
|
||||
'client', '_request', '_check_access', '_skip_warnings',
|
||||
}
|
||||
|
||||
def __init__(self, name, size_limit=1024, duration=None, context=True):
|
||||
def __init__(
|
||||
self, name, size_limit=1024, duration=None, context=True,
|
||||
context_ignored_keys=None):
|
||||
assert ((context_ignored_keys is not None and context)
|
||||
or (context_ignored_keys is None)), (
|
||||
f"context_ignored_keys ({context_ignored_keys}) is not valid"
|
||||
f" in regards to context ({context}).")
|
||||
self._name = name
|
||||
self.size_limit = size_limit
|
||||
self.context = context
|
||||
self.context_ignored_keys = set()
|
||||
if context and context_ignored_keys:
|
||||
self.context_ignored_keys.update(context_ignored_keys)
|
||||
self.hit = self.miss = 0
|
||||
if isinstance(duration, dt.timedelta):
|
||||
self.duration = duration
|
||||
@@ -93,10 +105,9 @@ class BaseCache(object):
|
||||
def _key(self, key):
|
||||
if self.context:
|
||||
context = Transaction().context.copy()
|
||||
context.pop('client', None)
|
||||
context.pop('_request', None)
|
||||
context.pop('_check_access', None)
|
||||
context.pop('_skip_warnings', None)
|
||||
for k in (self.__class__.context_ignored_keys
|
||||
| self.context_ignored_keys):
|
||||
context.pop(k, None)
|
||||
return (key, Transaction().user, freeze(context))
|
||||
return key
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@ from trytond.transaction import Transaction
|
||||
|
||||
cache = MemoryCache('test.cache')
|
||||
cache_expire = MemoryCache('test.cache_expire', duration=1)
|
||||
cache_ignored_local_context = MemoryCache(
|
||||
'test.cache.ignored.local', context_ignored_keys={'ignored'})
|
||||
cache_ignored_global_context = MemoryCache('test.cache.ignored.global')
|
||||
|
||||
|
||||
class CacheTestCase(unittest.TestCase):
|
||||
@@ -64,6 +67,28 @@ class CacheTestCase(unittest.TestCase):
|
||||
with self.subTest(value=value):
|
||||
self.assertEqual(unfreeze(value), result)
|
||||
|
||||
@with_transaction()
|
||||
def test_ignored_context_key_global(self):
|
||||
"Test global keys are ignored from context"
|
||||
with Transaction().set_context(client='foo'):
|
||||
cache_ignored_global_context.set('key', 0)
|
||||
|
||||
with Transaction().set_context(client='bar'):
|
||||
value = cache_ignored_global_context.get('key')
|
||||
|
||||
self.assertEqual(value, 0)
|
||||
|
||||
@with_transaction()
|
||||
def test_ignored_context_key_local(self):
|
||||
"Test local keys are ignored from context"
|
||||
with Transaction().set_context(ignored='foo'):
|
||||
cache_ignored_local_context.set('key', 1)
|
||||
|
||||
with Transaction().set_context(ignored='bar'):
|
||||
value = cache_ignored_local_context.get('key')
|
||||
|
||||
self.assertEqual(value, 1)
|
||||
|
||||
|
||||
class MemoryCacheTestCase(unittest.TestCase):
|
||||
"Test Cache"
|
||||
|
||||
Reference in New Issue
Block a user