diff --git a/src/ansys/geometry/core/connection/product_instance.py b/src/ansys/geometry/core/connection/product_instance.py index 8944e53ffd..9e892dc22e 100644 --- a/src/ansys/geometry/core/connection/product_instance.py +++ b/src/ansys/geometry/core/connection/product_instance.py @@ -284,13 +284,25 @@ def prepare_and_start_backend( instance = ProductInstance(_start_program(args, env_copy).pid) + # Verify that the backend is ready to accept connections + # before returning the Modeler instance. + LOG.info("Waiting for backend to be ready...") + _wait_for_backend(host, port, timeout) + return Modeler( host=host, port=port, timeout=timeout, product_instance=instance, backend_type=backend_type ) -def get_available_port(): - """Return an available port to be used.""" +def get_available_port() -> int: + """ + Return an available port to be used. + + Returns + ------- + int + The available port. + """ sock = socket.socket() sock.bind((socket.gethostname(), 0)) port = sock.getsockname()[1] @@ -298,6 +310,34 @@ def get_available_port(): return port +def _wait_for_backend(host: str, port: int, timeout: int): + """ + Check if the backend is ready to accept connections. + + Parameters + ---------- + host : str + The backend's ip address. + port : int + The backend's port number. + timeout : int + The timeout in seconds. + """ + import time + + start_time = time.time() + while time.time() - start_time < timeout: + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + if s.connect_ex((host, port)) == 0: + LOG.debug("Backend is ready to accept connections.") + return + else: + LOG.debug("Still waiting for backend to be ready... Retrying in 5 seconds.") + time.sleep(5) + + raise ConnectionError("Timeout while waiting for backend to be ready.") + + def _is_port_available(port: int, host: str = "localhost") -> bool: """ Check whether the argument port is available or not.