@@ -284,20 +284,60 @@ def prepare_and_start_backend(
284284
285285 instance = ProductInstance (_start_program (args , env_copy ).pid )
286286
287+ # Verify that the backend is ready to accept connections
288+ # before returning the Modeler instance.
289+ LOG .info ("Waiting for backend to be ready..." )
290+ _wait_for_backend (host , port , timeout )
291+
287292 return Modeler (
288293 host = host , port = port , timeout = timeout , product_instance = instance , backend_type = backend_type
289294 )
290295
291296
292- def get_available_port ():
293- """Return an available port to be used."""
297+ def get_available_port () -> int :
298+ """
299+ Return an available port to be used.
300+
301+ Returns
302+ -------
303+ int
304+ The available port.
305+ """
294306 sock = socket .socket ()
295307 sock .bind ((socket .gethostname (), 0 ))
296308 port = sock .getsockname ()[1 ]
297309 sock .close ()
298310 return port
299311
300312
313+ def _wait_for_backend (host : str , port : int , timeout : int ):
314+ """
315+ Check if the backend is ready to accept connections.
316+
317+ Parameters
318+ ----------
319+ host : str
320+ The backend's ip address.
321+ port : int
322+ The backend's port number.
323+ timeout : int
324+ The timeout in seconds.
325+ """
326+ import time
327+
328+ start_time = time .time ()
329+ while time .time () - start_time < timeout :
330+ with socket .socket (socket .AF_INET , socket .SOCK_STREAM ) as s :
331+ if s .connect_ex ((host , port )) == 0 :
332+ LOG .debug ("Backend is ready to accept connections." )
333+ return
334+ else :
335+ LOG .debug ("Still waiting for backend to be ready... Retrying in 5 seconds." )
336+ time .sleep (5 )
337+
338+ raise ConnectionError ("Timeout while waiting for backend to be ready." )
339+
340+
301341def _is_port_available (port : int , host : str = "localhost" ) -> bool :
302342 """
303343 Check whether the argument port is available or not.
0 commit comments