allow caching with the demoting_error_warning property

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

View file

@ -559,6 +559,8 @@ async def test_cache_global_properties():
@pytest.mark.asyncio
async def test_callback_value_incr():
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])
@ -579,3 +581,30 @@ async def test_callback_value_incr():
assert await cfg.option('val1').value.get() == 2
assert await cfg.option('val2').value.get() == 2
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,
option_bag: OptionBag,
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
force_index = option_bag.index
@ -341,7 +342,7 @@ class Option(BaseOption):
if check_error and config_bag is not undefined and \
not 'validator' in config_bag.properties:
return
return False
def _is_not_unique(value, option_bag):
@ -390,7 +391,7 @@ class Option(BaseOption):
raise ValueError(_('which must not be a list').format(_value,
self.impl_get_display_name()))
if isinstance(_value, Calculation) and config_bag is undefined:
return
return False
if _value is not None:
if check_error:
# option validation
@ -467,6 +468,8 @@ class Option(BaseOption):
err_index),
ValueErrorWarning,
self.__class__.__name__, 0)
return False
return True
def _validate_calculator(self,
callback: Callable,

View file

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