From 709c0bf22896fbc04520fddad55d99d91c635e7d Mon Sep 17 00:00:00 2001 From: Emmanuel Garette Date: Wed, 20 Nov 2019 08:29:45 +0100 Subject: [PATCH] force_store_value for follower --- tiramisu/value.py | 82 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 25 deletions(-) diff --git a/tiramisu/value.py b/tiramisu/value.py index 1a72aa0..9af8d14 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -76,8 +76,7 @@ class Values(object): option_bag, check_error=True) # store value in cache - properties = option_bag.config_bag.properties - validator = 'validator' in properties and 'demoting_error_warning' not in properties + 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, @@ -102,7 +101,7 @@ class Values(object): if 'force_metaconfig_on_freeze' in option_bag.properties: settings = option_bag.config_bag.context.cfgimpl_get_settings() if 'force_metaconfig_on_freeze' in option_bag.option.impl_getproperties() and \ - not settings._p_.getproperties(option_bag.path, frozenset()): + not settings._p_.getproperties(option_bag.path, None, frozenset()): # if force_metaconfig_on_freeze is only in option (not in config) return option_bag.config_bag.context.impl_type == 'config' else: @@ -150,12 +149,13 @@ class Values(object): value = self.calc_value(option_bag, value) return value - def calc_value(self, option_bag, value): + def calc_value(self, option_bag, value, reset_cache=True): if isinstance(value, Calculation): - value = value.execute(option_bag) + value = value.execute(option_bag, leadership_must_have_index=True) elif isinstance(value, (list, tuple)): value = list(self._do_value_list(value, option_bag)) - self.calculate_reset_cache(option_bag, value) + if reset_cache: + self.calculate_reset_cache(option_bag, value) return value def getdefaultvalue(self, @@ -267,13 +267,7 @@ class Values(object): "convenience method to know if an option is empty" empty = opt._empty if index in [None, undefined] and opt.impl_is_multi(): - if force_allow_empty_list: - allow_empty_list = True - else: - allow_empty_list = opt.impl_allow_empty_list() - if allow_empty_list is undefined: - allow_empty_list = opt.impl_is_follower() - isempty = value is None or (not allow_empty_list and value == []) or \ + isempty = value is None or (not force_allow_empty_list and value == []) or \ None in value or empty in value else: isempty = value is None or value == empty or (opt.impl_is_submulti() and value == []) @@ -294,7 +288,25 @@ class Values(object): self._setvalue(option_bag, value, owner, - commit=_commit) + commit=False) + setting_properties = option_bag.config_bag.properties + validator = 'validator' in setting_properties and 'demoting_error_warning' not in setting_properties + if validator: + cache = option_bag.config_bag.context._impl_values_cache + cache.setcache(option_bag.path, + option_bag.index, + value, + option_bag.properties, + setting_properties, + validator) + if 'force_store_value' in setting_properties and option_bag.option.impl_is_leader(): + option_bag.option.impl_get_leadership().follower_force_store_value(self, + value, + option_bag, + owners.forced, + _commit=_commit) + if _commit: + self._p_.commit() def setvalue_validation(self, value, @@ -303,10 +315,11 @@ class Values(object): # First validate properties with this value opt = option_bag.option settings.validate_frozen(option_bag) - settings.validate_mandatory(value, + val = self.calc_value(option_bag, value, False) + settings.validate_mandatory(val, option_bag) # Value must be valid for option - opt.impl_validate(value, + opt.impl_validate(val, option_bag, check_error=True) if 'warnings' in option_bag.config_bag.properties: @@ -449,6 +462,7 @@ class Values(object): context = option_bag.config_bag.context hasvalue = self._p_.hasvalue(option_bag.path) + setting_properties = option_bag.config_bag.properties if hasvalue and 'validator' in option_bag.config_bag.properties: fake_context = context._gen_fake_values() @@ -469,7 +483,7 @@ class Values(object): option_bag, _commit=_commit) if hasvalue: - if 'force_store_value' in option_bag.properties: + if 'force_store_value' in option_bag.config_bag.properties and 'force_store_value' in option_bag.properties: value = self.getdefaultvalue(option_bag) self._setvalue(option_bag, @@ -477,9 +491,19 @@ class Values(object): owners.forced, commit=_commit) else: + # for leader only + value = None self._p_.resetvalue(option_bag.path, _commit) context.cfgimpl_reset_cache(option_bag) + if 'force_store_value' in setting_properties and option_bag.option.impl_is_leader(): + if value is None: + value = self.getdefaultvalue(option_bag) + option_bag.option.impl_get_leadership().follower_force_store_value(self, + value, + option_bag, + owners.forced, + _commit=_commit) def reset_follower(self, option_bag, @@ -487,7 +511,8 @@ class Values(object): if self._p_.hasvalue(option_bag.path, index=option_bag.index): context = option_bag.config_bag.context - if 'validator' in option_bag.config_bag.properties: + setting_properties = option_bag.config_bag.properties + if 'validator' in setting_properties: fake_context = context._gen_fake_values() fake_value = fake_context.cfgimpl_get_values() config_bag = option_bag.config_bag.copy() @@ -499,9 +524,17 @@ class Values(object): value = fake_value.getdefaultvalue(soption_bag) fake_value.setvalue_validation(value, soption_bag) - self._p_.resetvalue_index(option_bag.path, - option_bag.index, - _commit) + if 'force_store_value' in setting_properties and 'force_store_value' in option_bag.properties: + value = self.getdefaultvalue(option_bag) + + self._setvalue(option_bag, + value, + owners.forced, + commit=_commit) + else: + self._p_.resetvalue_index(option_bag.path, + option_bag.index, + _commit) context.cfgimpl_reset_cache(option_bag) def reset_leadership(self, @@ -558,8 +591,7 @@ class Values(object): subconfig, od_config_bag): settings = context.cfgimpl_get_settings() - for option in description.get_children(config_bag, - context): + for option in description.get_children(config_bag): name = option.impl_getname() path = '.'.join(currpath + [name]) @@ -599,11 +631,11 @@ class Values(object): path, index, config_bag) - if 'mandatory' in option_bag.properties: + if 'mandatory' in option_bag.properties or 'empty' in option_bag.properties: subconfig.getattr(name, option_bag) except PropertiesOptionError as err: - if err.proptype == ['mandatory']: + if err.proptype in (['mandatory'], ['empty']): yield path except ConfigError: pass