@@ -148,31 +148,13 @@ async def start(self, start_wait: float = 5.0) -> None:
148148 try :
149149 await self .__start_up (start_wait )
150150 except BaseException :
151- # Catch BaseException so a cancelled start (CancelledError) also
152- # releases the components __start_up began; re-raise propagates it.
153- await self ._cleanup_partial_start ()
151+ # Catch BaseException, not Exception, so a cancelled start
152+ # (CancelledError) also tears down what __start_up began.
153+ self ._closed = True
154+ await self ._close_components ()
154155 raise
155156
156- async def _cleanup_partial_start (self ):
157- """Release any resources that were partially created during a failed
158- __start_up."""
159- for name , stop in (
160- ("data system" , self ._data_system .stop ),
161- ("big-segment store manager" , self .__big_segment_store_manager .stop ),
162- ("event processor" , self ._event_processor .stop ),
163- ):
164- try :
165- await stop ()
166- except Exception as e :
167- log .warning ("Error stopping %s during failed start: %s" , name , e )
168- if self ._session is not None :
169- try :
170- await self ._session .close ()
171- except Exception as e :
172- log .warning ("Error closing HTTP session during failed start: %s" , e )
173- self ._session = None
174-
175- async def close (self , close_timeout : float = 2.0 ) -> None :
157+ async def close (self ) -> None :
176158 """Shut down the client and release all resources.
177159
178160 Safe to call multiple times — subsequent calls are no-ops.
@@ -184,29 +166,26 @@ async def close(self, close_timeout: float = 2.0) -> None:
184166
185167 # A client that was never started has nothing running to release.
186168 if self ._started :
187- try :
188- await asyncio .wait_for (self ._close_components (), timeout = close_timeout )
189- except asyncio .TimeoutError :
190- log .warning ("Timed out closing AsyncLDClient components" )
191- except Exception as e :
192- log .warning ("Error closing AsyncLDClient components: %s" , e )
193-
194- if self ._session is not None :
195- try :
196- await self ._session .close ()
197- except Exception as e :
198- log .warning ("Error closing HTTP session: %s" , e )
169+ await self ._close_components ()
199170
200171 async def _close_components (self ):
201- """Releases the threads and network connections used by the SDK
202- components. The public :meth:`close` wraps this with a timeout."""
172+ """Stop the SDK components and release the shared HTTP session."""
203173 log .info ("Closing LaunchDarkly client.." )
174+
204175 await self ._data_system .stop ()
205176 await self .__big_segment_store_manager .stop ()
206177
207- # The event processor is last because it may still be sending events that were generated by the other components.
178+ # The event processor is last because it may still be sending events the
179+ # other components generated.
208180 await self ._event_processor .stop ()
209181
182+ if self ._session is not None :
183+ try :
184+ await self ._session .close ()
185+ except Exception as e :
186+ log .warning ("Error closing HTTP session: %s" , e )
187+ self ._session = None
188+
210189 async def __start_up (self , start_wait : float ):
211190 environment_metadata = get_environment_metadata (self ._config , "python-server-sdk-async" )
212191 plugin_hooks = get_plugin_hooks (self ._config .plugins , environment_metadata )
0 commit comments