Add kwarg function key generator

Added 'kwarg_function_key_generator' function, as a wrapper of
dogpile.cache's 'kwarg_function_key_generator'. This function allows
to a region to memoize from a function having keyword arguments.

Change-Id: I1bd762810ee0491c8bd96ccc92c49d3c0a1a08e9
Partial-Bug: #1696501
This commit is contained in:
Rodolfo Alonso Hernandez 2017-06-13 16:14:34 +01:00
parent 6a4e6df734
commit 6041068f77
2 changed files with 61 additions and 21 deletions

View File

@ -151,7 +151,28 @@ def _sha1_mangle_key(key):
return util.sha1_mangle_key(key)
def create_region():
def _key_generate_to_str(s):
# NOTE(morganfainberg): Since we need to stringify all arguments, attempt
# to stringify and handle the Unicode error explicitly as needed.
try:
return str(s)
except UnicodeEncodeError:
return s.encode('utf-8')
def function_key_generator(namespace, fn, to_str=_key_generate_to_str):
# NOTE(morganfainberg): This wraps dogpile.cache's default
# function_key_generator to change the default to_str mechanism.
return util.function_key_generator(namespace, fn, to_str=to_str)
def kwarg_function_key_generator(namespace, fn, to_str=_key_generate_to_str):
# NOTE(ralonsoh): This wraps dogpile.cache's default
# kwarg_function_key_generator to change the default to_str mechanism.
return util.kwarg_function_key_generator(namespace, fn, to_str=to_str)
def create_region(function=function_key_generator):
"""Create a region.
This is just dogpile.cache.make_region, but the key generator has a
@ -162,13 +183,15 @@ def create_region():
You must call :func:`configure_cache_region` with this region before
a memoized method is called.
:param function: function used to generate a unique key depending on the
arguments of the decorated function
:type function: function
:returns: The new region.
:rtype: :class:`dogpile.cache.region.CacheRegion`
"""
return dogpile.cache.make_region(
function_key_generator=_function_key_generator)
return dogpile.cache.make_region(function_key_generator=function)
def configure_cache_region(conf, region):
@ -276,21 +299,6 @@ def _get_expiration_time_fn(conf, group):
return get_expiration_time
def _key_generate_to_str(s):
# NOTE(morganfainberg): Since we need to stringify all arguments, attempt
# to stringify and handle the Unicode error explicitly as needed.
try:
return str(s)
except UnicodeEncodeError:
return s.encode('utf-8')
def _function_key_generator(namespace, fn, to_str=_key_generate_to_str):
# NOTE(morganfainberg): This wraps dogpile.cache's default
# function_key_generator to change the default to_str mechanism.
return util.function_key_generator(namespace, fn, to_str=to_str)
def get_memoization_decorator(conf, region, group, expiration_group=None):
"""Build a function based on the `cache_on_arguments` decorator.

View File

@ -74,6 +74,11 @@ class CacheRegionTest(BaseTestCase):
self.region = cache.create_region()
cache.configure_cache_region(self.config_fixture.conf, self.region)
self.region.wrap(TestProxy)
self.region_kwargs = cache.create_region(
function=cache.kwarg_function_key_generator)
cache.configure_cache_region(self.config_fixture.conf,
self.region_kwargs)
self.region_kwargs.wrap(TestProxy)
self.test_value = TestProxyValue('Decorator Test')
def _add_test_caching_option(self):
@ -86,12 +91,13 @@ class CacheRegionTest(BaseTestCase):
self.config_fixture.register_opt(
cfg.IntOpt('cache_time'), group=TEST_GROUP2)
def _get_cacheable_function(self):
def _get_cacheable_function(self, region=None):
region = region if region else self.region
memoize = cache.get_memoization_decorator(
self.config_fixture.conf, self.region, group='cache')
self.config_fixture.conf, region, group='cache')
@memoize
def cacheable_function(value):
def cacheable_function(value=0):
return value
return cacheable_function
@ -309,6 +315,32 @@ class CacheRegionTest(BaseTestCase):
self.config_fixture.conf,
"bogus")
def test_function_key_generator_with_kwargs(self):
cacheable_function = self._get_cacheable_function()
self.config_fixture.config(group='cache', enabled=True)
self.assertRaises(ValueError,
cacheable_function,
value=self.test_value)
def test_kwarg_function_key_generator_no_kwargs(self):
cacheable_function = self._get_cacheable_function(
region=self.region_kwargs)
self.config_fixture.config(group='cache', enabled=True)
cacheable_function(self.test_value)
cached_value = cacheable_function(self.test_value)
self.assertTrue(cached_value.cached)
def test_kwarg_function_key_generator_with_kwargs(self):
cacheable_function = self._get_cacheable_function(
region=self.region_kwargs)
self.config_fixture.config(group='cache', enabled=True)
cacheable_function(value=self.test_value)
cached_value = cacheable_function(value=self.test_value)
self.assertTrue(cached_value.cached)
class UTF8KeyManglerTests(BaseTestCase):