2626)
2727from ldclient .impl .util import Result
2828from ldclient .integrations import Redis
29+ from ldclient .integrations .overrides import FileOverrideSourceBuilder
2930from ldclient .interfaces import DataStoreMode
3031from ldclient .migrations import (
3132 AsyncMigratorBuilder ,
@@ -56,8 +57,10 @@ async def start(self):
5657 }
5758
5859 datasystem_config = config_params .get ('dataSystem' )
60+ if config_params .get ('overrides' ) is not None and datasystem_config is None :
61+ raise ValueError ("flag overrides require the data system to be configured" )
5962 if datasystem_config is not None :
60- opts ["datasystem_config" ] = _build_async_data_system (datasystem_config , opts )
63+ opts ["datasystem_config" ] = _build_async_data_system (datasystem_config , opts , config_params . get ( 'overrides' ) )
6164 elif config_params .get ("streaming" ) is not None :
6265 streaming = config_params ["streaming" ]
6366 if streaming .get ("baseUri" ) is not None :
@@ -297,13 +300,13 @@ def _set_optional_value(params_in: dict, name_in: str, func: Callable[[Any], Any
297300 func (params_in [name_in ])
298301
299302
300- def _build_async_data_system (datasystem_config : dict , opts : dict ) -> AsyncDataSystemConfig :
303+ def _build_async_data_system (datasystem_config : dict , opts : dict , overrides_config : Optional [ dict ] = None ) -> AsyncDataSystemConfig :
301304 """Build an AsyncDataSystemConfig from the harness's dataSystem config.
302305
303306 Wires the FDv2 initializers, the ordered synchronizer chain, the FDv1
304- fallback synchronizer, the payload filter, and an optional async
305- persistent store. The async client injects its shared aiohttp session
306- into these builders when it starts.
307+ fallback synchronizer, the payload filter, an optional async persistent
308+ store, and the optional file-based override source. The async client
309+ injects its shared aiohttp session into these builders when it starts.
307310 """
308311 initializers : Optional [list ] = None
309312 init_configs = datasystem_config .get ('initializers' )
@@ -356,6 +359,9 @@ def _build_async_data_system(datasystem_config: dict, opts: dict) -> AsyncDataSy
356359 "fdv1_fallback_synchronizer" : fdv1_fallback_synchronizer ,
357360 }
358361
362+ if overrides_config is not None :
363+ ds_kwargs ["override_source" ] = _make_override_source (overrides_config )
364+
359365 store_config = datasystem_config .get ("store" )
360366 if store_config is not None :
361367 persistent_store_config = store_config .get ("persistentDataStore" )
@@ -370,6 +376,18 @@ def _build_async_data_system(datasystem_config: dict, opts: dict) -> AsyncDataSy
370376 return AsyncDataSystemConfig (** ds_kwargs )
371377
372378
379+ def _make_override_source (params : dict ) -> FileOverrideSourceBuilder :
380+ """
381+ Builds the file-based override source from the harness's overrides configuration. The
382+ files are written by the harness on a file system shared with this service.
383+ """
384+ builder = FileOverrideSourceBuilder (params ["filePaths" ])
385+ _set_optional_value (params , "duplicateKeysHandling" , builder .duplicate_keys_handling )
386+ _set_optional_value (params , "changeDetection" , builder .change_detection )
387+ _set_optional_time (params , "pollIntervalMs" , builder .poll_interval )
388+ return builder
389+
390+
373391def _create_async_persistent_store (persistent_store_config : dict ):
374392 """Create an async persistent feature store from the harness config.
375393
0 commit comments