diff --git a/hermes_cli/gateway.py b/hermes_cli/gateway.py index 8d863fc7e6..9a358d95d6 100644 --- a/hermes_cli/gateway.py +++ b/hermes_cli/gateway.py @@ -4008,19 +4008,18 @@ def _wait_for_tcp_port_free(host: str, port: int, *, timeout: float = 10.0) -> b the race logs EADDRINUSE and keeps running with no API. Connection-refused means the listener is gone; a timed-out connect is a live listener with a slow accept queue. """ - deadline = time.monotonic() + timeout - while time.monotonic() < deadline: + def _port_free() -> bool: try: with socket.create_connection((host, port), timeout=0.2): - pass + return False except ConnectionRefusedError: return True except TimeoutError: - pass # a slow accept queue is still a live listener + return False # a slow accept queue is still a live listener except OSError: return True # unresolvable/unreachable address: nothing to wait for; the bind retry covers it - time.sleep(0.1) - return False + + return poll_until(_port_free, timeout, 0.1) def _wait_for_api_server_port_free(*, timeout: float = 10.0) -> bool: diff --git a/tools/voice_mode.py b/tools/voice_mode.py index 93a1f83a48..17f14b442c 100644 --- a/tools/voice_mode.py +++ b/tools/voice_mode.py @@ -371,9 +371,9 @@ def _sd_play_blocking(sd, audio, sample_rate: int, *, timeout: float, blocksize: """``sd.play`` then poll until idle or *timeout* (``sd.wait()`` has no timeout and hangs forever if the device stalls).""" sd.play(audio, samplerate=sample_rate, blocksize=blocksize) - deadline = time.monotonic() + timeout - while sd.get_stream() and sd.get_stream().active and time.monotonic() < deadline: - time.sleep(0.01) + from agent.deadline import poll_until + + poll_until(lambda: not (sd.get_stream() and sd.get_stream().active), timeout, 0.01) sd.stop()