1919import asyncio
2020import json
2121import logging
22+ import threading
2223from typing import Dict , Optional , Literal , Union , Any
2324from enum import Enum
2425import re
@@ -138,6 +139,7 @@ def __init__(self, app: App = None, default_config: Optional[Dict[str, str]] = N
138139 # fetched from RC servers via the load API, or via the set API.
139140 self ._cache = None
140141 self ._stringified_default_config : Dict [str , str ] = {}
142+ self ._lock = threading .RLock ()
141143
142144 # RC stores all remote values as string, but it's more intuitive
143145 # to declare default values with specific types, so this converts
@@ -148,7 +150,9 @@ def __init__(self, app: App = None, default_config: Optional[Dict[str, str]] = N
148150
149151 async def load (self ):
150152 """Fetches the server template and caches the data."""
151- self ._cache = await self ._rc_service .get_server_template ()
153+ rc_server_template = await self ._rc_service .get_server_template ()
154+ with self ._lock :
155+ self ._cache = rc_server_template
152156
153157 def evaluate (self , context : Optional [Dict [str , Union [str , int ]]] = None ) -> 'ServerConfig' :
154158 """Evaluates the cached server template to produce a ServerConfig.
@@ -167,12 +171,17 @@ def evaluate(self, context: Optional[Dict[str, Union[str, int]]] = None) -> 'Ser
167171 Call load() before calling evaluate().""" )
168172 context = context or {}
169173 config_values = {}
174+
175+ with self ._lock :
176+ template_conditions = self ._cache .conditions
177+ template_parameters = self ._cache .parameters
178+
170179 # Initializes config Value objects with default values.
171180 if self ._stringified_default_config is not None :
172181 for key , value in self ._stringified_default_config .items ():
173182 config_values [key ] = _Value ('default' , value )
174- self ._evaluator = _ConditionEvaluator (self . _cache . conditions ,
175- self . _cache . parameters , context ,
183+ self ._evaluator = _ConditionEvaluator (template_conditions ,
184+ template_parameters , context ,
176185 config_values )
177186 return ServerConfig (config_values = self ._evaluator .evaluate ())
178187
@@ -183,14 +192,19 @@ def set(self, template_data_json: str):
183192 template_data_json: A json string representing ServerTemplateData to be cached.
184193 """
185194 template_data_map = json .loads (template_data_json )
186- self ._cache = _ServerTemplateData (template_data_map )
195+ template_data = _ServerTemplateData (template_data_map )
196+
197+ with self ._lock :
198+ self ._cache = template_data
187199
188200 def to_json (self ):
189201 """Provides the server template in a JSON format to be used for initialization later."""
190202 if not self ._cache :
191203 raise ValueError ("""No Remote Config Server template in cache.
192204 Call load() before calling toJSON().""" )
193- return self ._cache .template_data_json
205+ with self ._lock :
206+ template_json = self ._cache .template_data_json
207+ return template_json
194208
195209
196210class ServerConfig :
0 commit comments