New cache layer for external sources

Add a separate cache for values coming from external sources,
this will protect us from having options from external sources
mutated when we reload the configuration files

Change-Id: Icf72f4e1745a0ddf53e661cc08d0fe7428cd9a41
Blueprint: oslo-config-drivers
This commit is contained in:
Raildo Mascena 2018-06-26 13:13:30 -03:00
parent b79f763b49
commit ce150b1037
1 changed files with 23 additions and 1 deletions

View File

@ -2408,6 +2408,7 @@ class ConfigOpts(collections.Mapping):
self._mutable_ns = None
self._mutate_hooks = set([])
self.__cache = {}
self.__drivers_cache = {}
self._config_opts = []
self._cli_opts = collections.deque()
self._validate_default_values = False
@ -2501,6 +2502,18 @@ class ConfigOpts(collections.Mapping):
return __inner
def __clear_drivers_cache(f):
@functools.wraps(f)
def __inner(self, *args, **kwargs):
if kwargs.pop('clear_drivers_cache', True):
result = f(self, *args, **kwargs)
self.__drivers_cache.clear()
return result
else:
return f(self, *args, **kwargs)
return __inner
def __call__(self,
args=None,
project=None,
@ -3105,10 +3118,18 @@ class ConfigOpts(collections.Mapping):
"Value for option %s is not valid: %s"
% (opt.name, str(ve)))
key = (group_name, name)
try:
return self.__drivers_cache[key]
except KeyError: # nosec: Valid control flow instruction
pass
for source in self._sources:
val = source.get(group_name, name, opt)
if val[0] != sources._NoValue:
return (convert(val[0]), val[1])
result = (convert(val[0]), val[1])
self.__drivers_cache[key] = result
return result
if 'default' in info:
return (self._substitute(info['default']), loc)
@ -3358,6 +3379,7 @@ class ConfigOpts(collections.Mapping):
return namespace
@__clear_cache
@__clear_drivers_cache
def reload_config_files(self):
"""Reload configure files and parse all options