@@ -197,6 +197,12 @@ async def __start_up(self, start_wait: float):
197197 # Start the big-segment status poll now that a loop is running.
198198 self .__big_segment_store_manager .start ()
199199
200+ # FDv2 builds its data sources from builders; wire the shared session into
201+ # them before starting (FDv1 pulls the session itself via its provider).
202+ datasystem_config = self ._config .datasystem_config
203+ if datasystem_config is not None and not self ._config .offline :
204+ self ._wire_data_source_sessions (datasystem_config )
205+
200206 if self ._config .offline :
201207 log .info ("Started LaunchDarkly Client in offline mode" )
202208
@@ -221,6 +227,10 @@ async def __start_up(self, start_wait: float):
221227 log .info ("Waiting up to " + str (start_wait ) + " seconds for LaunchDarkly client to initialize..." )
222228 await update_processor_ready .wait (start_wait )
223229
230+ # Warm the persistent store's initialized state so a store populated by
231+ # another process is recognized before the readiness check.
232+ await self ._data_system .refresh_availability ()
233+
224234 if self .is_initialized () is True :
225235 log .info ("Started LaunchDarkly Client: OK" )
226236 else :
@@ -243,7 +253,9 @@ def _make_data_system(self) -> AsyncDataSystem:
243253
244254 return AsyncFDv1 (self ._config , self ._select_feature_store (), self ._get_session )
245255
246- raise NotImplementedError ("FDv2 is not yet supported in the async client" )
256+ from ldclient .impl .datasystem .async_fdv2 import AsyncFDv2
257+
258+ return AsyncFDv2 (self ._config , datasystem_config )
247259
248260 def _select_feature_store (self ) -> AsyncFeatureStore :
249261 """Choose the async feature store for the v1 data system based on the
@@ -253,6 +265,34 @@ def _select_feature_store(self) -> AsyncFeatureStore:
253265 return AsyncInMemoryFeatureStore ()
254266 return feature_store
255267
268+ def _wire_data_source_sessions (self , data_system_config ) -> None :
269+ """Provide the client's aiohttp session to any async data source
270+ builders so the sources they build share the client's connection pool."""
271+ from ldclient .impl .datasourcev2 .async_polling import (
272+ AsyncFallbackToFDv1PollingDataSourceBuilder ,
273+ AsyncPollingDataSourceBuilder
274+ )
275+ from ldclient .impl .datasourcev2 .async_streaming import (
276+ AsyncStreamingDataSourceBuilder
277+ )
278+
279+ builders = list (data_system_config .initializers or []) + list (
280+ data_system_config .synchronizers or []
281+ )
282+ if data_system_config .fdv1_fallback_synchronizer is not None :
283+ builders .append (data_system_config .fdv1_fallback_synchronizer )
284+
285+ for builder in builders :
286+ if isinstance (
287+ builder ,
288+ (
289+ AsyncFallbackToFDv1PollingDataSourceBuilder ,
290+ AsyncPollingDataSourceBuilder ,
291+ AsyncStreamingDataSourceBuilder ,
292+ ),
293+ ):
294+ builder .session (self ._get_session ())
295+
256296 async def __register_plugins (self , environment_metadata : EnvironmentMetadata ):
257297 for plugin in self ._config .plugins :
258298 try :
@@ -455,6 +495,11 @@ async def _evaluate_internal(self, key: str, context: Context, default: Any, eve
455495 if self ._config .offline :
456496 return EvaluationDetail (default , None , error_reason ('CLIENT_NOT_READY' )), None
457497
498+ # Refresh the store's initialized state only while still uninitialized;
499+ # once initialized or a basis arrives, the gate reads a cached value.
500+ if self ._data_system .data_availability == DataAvailability .DEFAULTS :
501+ await self ._data_system .refresh_availability ()
502+
458503 if self ._data_system .data_availability != DataAvailability .REFRESHED :
459504 if self ._data_system .data_availability == DataAvailability .CACHED :
460505 log .warning ("Feature Flag evaluation attempted before client has initialized - using last known values from feature store for feature key: " + key )
@@ -526,6 +571,11 @@ async def all_flags_state(self, context: Context, **kwargs) -> FeatureFlagsState
526571 log .warning ("all_flags_state() called, but client is in offline mode. Returning empty state" )
527572 return FeatureFlagsState (False )
528573
574+ # Refresh the store's initialized state only while still uninitialized;
575+ # once initialized or a basis arrives, the gate reads a cached value.
576+ if self ._data_system .data_availability == DataAvailability .DEFAULTS :
577+ await self ._data_system .refresh_availability ()
578+
529579 if self ._data_system .data_availability != DataAvailability .REFRESHED :
530580 if self ._data_system .data_availability == DataAvailability .CACHED :
531581 log .warning ("all_flags_state() called before client has finished initializing! Using last known values from feature store" )
0 commit comments