allow caching with the demoting_error_warning property

This commit is contained in:
Emmanuel Garette 2021-03-21 14:51:12 +01:00
parent 6084487d08
commit 33f9cbdc64
3 changed files with 60 additions and 25 deletions

View File

@ -559,6 +559,8 @@ async def test_cache_global_properties():
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_callback_value_incr(): async def test_callback_value_incr():
global incr
incr = -1
val1 = IntOption('val1', "", Calculation(return_incr), properties=('expire',)) val1 = IntOption('val1', "", Calculation(return_incr), properties=('expire',))
val2 = IntOption('val2', "", Calculation(calc_value, Params(ParamOption(val1)))) val2 = IntOption('val2', "", Calculation(calc_value, Params(ParamOption(val1))))
od1 = OptionDescription('rootconfig', '', [val1, val2]) od1 = OptionDescription('rootconfig', '', [val1, val2])
@ -579,3 +581,30 @@ async def test_callback_value_incr():
assert await cfg.option('val1').value.get() == 2 assert await cfg.option('val1').value.get() == 2
assert await cfg.option('val2').value.get() == 2 assert await cfg.option('val2').value.get() == 2
assert not await list_sessions() assert not await list_sessions()
@pytest.mark.asyncio
async def test_callback_value_incr_demoting():
global incr
incr = -1
val1 = IntOption('val1', "", Calculation(return_incr), properties=('expire',))
val2 = IntOption('val2', "", Calculation(calc_value, Params(ParamOption(val1))))
od1 = OptionDescription('rootconfig', '', [val1, val2])
async with await Config(od1) as cfg:
await cfg.property.add('demoting_error_warning')
assert await cfg.cache.get_expiration_time() == 5
await cfg.cache.set_expiration_time(1)
assert await cfg.cache.get_expiration_time() == 1
await cfg.property.read_write()
assert await cfg.option('val1').value.get() == 1
sleep(1)
assert await cfg.option('val2').value.get() == 1
sleep(1)
assert await cfg.option('val1').value.get() == 1
assert await cfg.option('val2').value.get() == 1
sleep(2)
assert await cfg.option('val1').value.get() == 2
assert await cfg.option('val2').value.get() == 2
assert await cfg.option('val1').value.get() == 2
assert await cfg.option('val2').value.get() == 2
assert not await list_sessions()

View File

@ -333,7 +333,8 @@ class Option(BaseOption):
value: Any, value: Any,
option_bag: OptionBag, option_bag: OptionBag,
check_error: bool=True) -> None: check_error: bool=True) -> None:
""" """Return True if value is really valid
If not validate or invalid return it returns False
""" """
config_bag = option_bag.config_bag config_bag = option_bag.config_bag
force_index = option_bag.index force_index = option_bag.index
@ -341,7 +342,7 @@ class Option(BaseOption):
if check_error and config_bag is not undefined and \ if check_error and config_bag is not undefined and \
not 'validator' in config_bag.properties: not 'validator' in config_bag.properties:
return return False
def _is_not_unique(value, option_bag): def _is_not_unique(value, option_bag):
@ -390,7 +391,7 @@ class Option(BaseOption):
raise ValueError(_('which must not be a list').format(_value, raise ValueError(_('which must not be a list').format(_value,
self.impl_get_display_name())) self.impl_get_display_name()))
if isinstance(_value, Calculation) and config_bag is undefined: if isinstance(_value, Calculation) and config_bag is undefined:
return return False
if _value is not None: if _value is not None:
if check_error: if check_error:
# option validation # option validation
@ -467,6 +468,8 @@ class Option(BaseOption):
err_index), err_index),
ValueErrorWarning, ValueErrorWarning,
self.__class__.__name__, 0) self.__class__.__name__, 0)
return False
return True
def _validate_calculator(self, def _validate_calculator(self,
callback: Callable, callback: Callable,

View File

@ -57,11 +57,12 @@ class Values:
None, None,
new=True) new=True)
#______________________________________________________________________ #______________________________________________________________________
# get value # get value
async def get_cached_value(self, async def get_cached_value(self,
option_bag): option_bag: OptionBag,
) -> Any:
"""get value directly in cache if set """get value directly in cache if set
otherwise calculated value and set it in cache otherwise calculated value and set it in cache
@ -75,32 +76,34 @@ class Values:
option_bag.index, option_bag.index,
setting_properties, setting_properties,
option_bag.properties, option_bag.properties,
'value') 'value',
# FIXME hu? validated or is_cached? )
if not validated:
# no cached value so get value # no cached value so get value
if not is_cached:
value = await self.getvalue(option_bag) value = await self.getvalue(option_bag)
# validate value # validates and warns value
if not validated:
validate = await option_bag.option.impl_validate(value,
option_bag,
check_error=True,
)
if 'warnings' in setting_properties:
await option_bag.option.impl_validate(value, await option_bag.option.impl_validate(value,
option_bag, option_bag,
check_error=True) check_error=False,
# store value in cache )
validator = 'validator' in setting_properties and 'demoting_error_warning' not in setting_properties # set value to cache
if not is_cached or validator: if not is_cached:
cache.setcache(option_bag.path, cache.setcache(option_bag.path,
option_bag.index, option_bag.index,
value, value,
option_bag.properties, option_bag.properties,
setting_properties, setting_properties,
validator) validate,
if 'warnings' in setting_properties: )
await option_bag.option.impl_validate(value,
option_bag,
check_error=False)
if isinstance(value, list): if isinstance(value, list):
# return a copy, so value cannot be modified # return a copy, so value cannot be modified
from copy import copy value = value.copy()
value = copy(value)
# and return it # and return it
return value return value