Source code for parameter_info.cached_info
# Copyright (c) Fraunhofer MEVIS, Germany. All rights reserved.
# **InsertLicense** code author="Jan-Martin Kuhnigk"
from parameter_info.indirect_info import IndirectParameterInfo, InformationSource, Query, \
raise_InformationSourceKeyError
[docs]class CachedParameterInfo(IndirectParameterInfo):
"""
Extension of IndirectParameterInfo providing a cache for data retrieved from a user-defined information source.
"""
def __init__(self, default_information_source_query):
super(CachedParameterInfo, self).__init__(default_information_source_query)
assert issubclass( default_information_source_query.query_class, CachedQuery )
[docs] def clear_cached_values(self ):
"""
Clears all cached values, forcing to update from source on next request. Works recursively, as long
as the child CachedParameterInfo is a direct child.
:return: None
"""
for key in self:
if isinstance( self._get_internal_value( key ), CachedParameterInfo ):
self._get_internal_value( key ).clear_cached_values()
else:
self._get_internal_value( key ).clear()
# THIS IS THE VERSION THAT SHOULD WORK FULLY RECURSIVELY
# TODO: Add tests, check if we really need to differentiate between IndirectParamInfo and dict when descending
# def clear_cached_values(self ):
# """
# Clears all cached values, forcing to update from source on next request. Works recursively, as long
# as the child CachedParameterInfo is a direct child.
# :return: None
# """
# self.clear_cached_values_recursively( self )
#
# @classmethod
# def clear_cached_values_recursively( cls, d ):
# for key in d:
# is_child_node = False
# if isinstance( d, IndirectParameterInfo ):
# if isinstance( d._get_internal_value( key ), CachedQuery ):
# d._get_internal_value( key ).clear()
# if not isinstance( d._get_internal_value( key ), Query ) and isinstance( d[key], dict ):
# is_child_node = True
# elif isinstance( d[ key ], dict ):
# is_child_node = True
# if is_child_node:
# cls.clear_cached_values_recursively( d[ key ] )
[docs] def update_cache_from_source( self ):
"""
Refreshes (overwrites) all (possibly cached) values with those from the information source.
Works recursively, as long as the child CachedParameterInfo is a direct child.
:return: None
"""
for key in self:
if isinstance( self._get_internal_value( key ), CachedParameterInfo ):
self._get_internal_value( key ).update_cache_from_source()
else:
self._get_internal_value( key ).update()
[docs]class CachedQuery(Query):
def __init__(self, getter_cb, *getter_args, **getter_kwargs):
"""
See super class for parameter documentation
"""
super(CachedQuery, self).__init__( getter_cb, *getter_args, **getter_kwargs)
self.__has_cached_value = False
self.__cached_value = None
def __call__(self):
"""
Executes the query, returning result value.
:return: The cached value if existing, otherwise updates the cache first.
"""
if not self.__has_cached_value:
self.update()
return self.__cached_value
[docs] def clear(self):
"""
Clears the cache
:return: None
"""
self.__has_cached_value = False
self.__cached_value = None
[docs] def update(self):
"""
Refreshes the cache from the source.
:return: None
"""
self.__cached_value = super(CachedQuery, self).__call__()
self.__has_cached_value = True
def _has_cached_value(self):
"""
Currently only required for testing, thus protected.
:return: True if a cached value exists
"""
return self.__has_cached_value