From 658da9822226a88a598da2e6e929ec51abc400a9 Mon Sep 17 00:00:00 2001 From: Tsiry Sandratraina Date: Mon, 10 Aug 2026 18:51:02 +0300 Subject: [PATCH] sdk(python): fix flaky WS e2e close-detection tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI caught it: the fake WS test server's close() called conn.close() while its own background _read_loop thread could still be blocked in conn.recv() on that same fd. Closing a socket concurrently with a blocking read on it from another thread isn't reliably immediate across platforms, so the client's close-detection sometimes never saw the FIN in time and the test hung until its 5s timeout. shutdown(SHUT_RDWR) before close() is the standard fix — it's built to safely unblock a concurrent blocking read and deliver the peer a clean FIN right away. 8/8 repeated local runs clean after the fix. --- sdk/python/tests/test_transport_ws_e2e.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sdk/python/tests/test_transport_ws_e2e.py b/sdk/python/tests/test_transport_ws_e2e.py index 5f48db5..df108aa 100644 --- a/sdk/python/tests/test_transport_ws_e2e.py +++ b/sdk/python/tests/test_transport_ws_e2e.py @@ -127,6 +127,19 @@ class _TestWSServer: def close(self) -> None: if self.conn is not None: + # shutdown() first: the server's own `_read_loop` thread may + # still be blocked in `conn.recv()` on this exact fd, and + # closing a socket concurrently with a blocking read on it from + # another thread is not reliably safe or immediate across + # platforms (a classic POSIX footgun — the read may not unblock + # promptly, or a since-reused fd number could even be affected). + # shutdown(SHUT_RDWR) is specifically designed to deliver EOF to + # a concurrent blocking read and to send the peer a clean FIN + # right away, which close() alone does not guarantee. + try: + self.conn.shutdown(socket.SHUT_RDWR) + except OSError: + pass try: self.conn.close() except OSError: -- 2.51.2