2222
2323
2424class RuntimeConfig :
25- def __init__ (self , init_settings : SettingsType , source : BaseSource , refresh_interval : float ) -> None :
25+ def __init__ (
26+ self ,
27+ init_settings : SettingsType ,
28+ source : BaseSource ,
29+ refresh_interval : float ,
30+ require_complete_init : bool = True ,
31+ ) -> None :
2632 self ._init_settings : SettingsType = copy .deepcopy (init_settings )
27- self ._settings : SettingsType = {}
33+ self ._settings : SettingsType = copy .deepcopy (init_settings )
34+ self ._initialized = False
2835
2936 self ._source = source
3037 self ._settings_merger = SettingsMerger (init_settings = init_settings )
3138 self ._periodic_refresh_task : asyncio .Task [None ] = periodic_task (self .refresh , callback_time = refresh_interval )
39+ self ._require_complete_init = require_complete_init
3240
3341 @staticmethod
3442 async def create (
3543 init_settings : t .Dict [str , t .Any ],
3644 source : BaseSource | None = None ,
3745 refresh_interval : float = 10 ,
46+ require_complete_init : bool = True ,
3847 ) -> RuntimeConfig :
3948 """
4049 Creates and initializes an instance of the class. You should always use this method to instantiate a class.
4150 :param init_settings: dictionary with default settings that you can then override.
4251 :param source: the source from which the actual values of the variables will be retrieved.
4352 :param refresh_interval: the frequency with which updates will be requested from the source.
53+ :param require_complete_init: if set to true, exceptions that occur during the first time settings are
54+ received from an external source will not be caught
4455 :return: initialized class instance.
4556 """
4657 if 'inst' in _instance :
@@ -56,24 +67,37 @@ async def create(
5667 )
5768 source = sources .ConfigServerSrc (host = host , service_name = service_name )
5869
59- inst = RuntimeConfig (init_settings = init_settings , source = source , refresh_interval = refresh_interval )
70+ inst = RuntimeConfig (
71+ init_settings = init_settings ,
72+ source = source ,
73+ refresh_interval = refresh_interval ,
74+ require_complete_init = require_complete_init ,
75+ )
6076 _instance ['inst' ] = inst
6177 await inst .refresh ()
78+ inst ._initialized = True
6279 return inst
6380
6481 async def refresh (self ) -> None :
82+ def _check_inst_initialization (inst : RuntimeConfig , exception : Exception ) -> None :
83+ if not inst ._initialized and inst ._require_complete_init :
84+ raise exception
85+
6586 extracted_settings = []
6687 try :
6788 extracted_settings = await self ._source .get_settings ()
6889 except ValidationError as exc :
69- logger .error (str (exc ), exc_info = True )
70- except Exception :
71- logger .error ('An unexpected error occurred while fetching new settings from the server' , exc_info = True )
90+ logger .error ("Fetched not valid data from remote source" , exc_info = True )
91+ _check_inst_initialization (self , exc )
92+ except Exception as exc :
93+ logger .error ('Fetching new settings from a remote source failed' , exc_info = True )
94+ _check_inst_initialization (self , exc )
7295
7396 try :
7497 self ._settings = await self ._settings_merger .merge (extracted_settings = extracted_settings )
75- except Exception :
76- logger .error ('An unexpected error occurred while merge settings' , exc_info = True )
98+ except Exception as exc :
99+ logger .error ('Merge settings error' , exc_info = True )
100+ _check_inst_initialization (self , exc )
77101
78102 def get (self , setting_name : str , default : t .Any = None ) -> t .Any :
79103 return self ._settings .get (setting_name , default )
0 commit comments