From a7ec8b112e93e3544e4122eb5b57189f3f838b1e Mon Sep 17 00:00:00 2001 From: bdhimes Date: Fri, 26 Sep 2025 21:03:21 +0200 Subject: [PATCH 1/5] Improve the canceled task handling --- async_substrate_interface/async_substrate.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/async_substrate_interface/async_substrate.py b/async_substrate_interface/async_substrate.py index cbe18e2..e06fec0 100644 --- a/async_substrate_interface/async_substrate.py +++ b/async_substrate_interface/async_substrate.py @@ -610,6 +610,7 @@ async def connect(self, force=False): try: await asyncio.wait_for(self._cancel(), timeout=10.0) except asyncio.TimeoutError: + logger.debug(f"Timed out waiting for cancellation") pass self.ws = await asyncio.wait_for( connect(self.ws_url, **self._options), timeout=10.0 @@ -618,8 +619,9 @@ async def connect(self, force=False): self._send_recv_task = asyncio.get_running_loop().create_task( self._handler(self.ws) ) + logger.debug("Websocket handler attached.") - async def _handler(self, ws: ClientConnection) -> None: + async def _handler(self, ws: ClientConnection) -> Union[None, Exception]: recv_task = asyncio.create_task(self._start_receiving(ws)) send_task = asyncio.create_task(self._start_sending(ws)) done, pending = await asyncio.wait( @@ -652,6 +654,7 @@ async def _handler(self, ws: ClientConnection) -> None: ) await self.connect(True) await self._handler(ws=self.ws) + return None elif isinstance(e := recv_task.result(), Exception): return e elif isinstance(e := send_task.result(), Exception): @@ -834,8 +837,10 @@ async def retrieve(self, item_id: str) -> Optional[dict]: except asyncio.QueueEmpty: pass if self._send_recv_task is not None and self._send_recv_task.done(): - if isinstance(e := self._send_recv_task.result(), Exception): - raise e + if not self._send_recv_task.cancelled(): + if isinstance((e := self._send_recv_task.exception()), Exception): + logger.exception(f"Websocket sending exception: {e}") + raise e await asyncio.sleep(0.1) return None From 9d9ea8b5850c61d1f4ab6581251f38aba280bf02 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Fri, 26 Sep 2025 21:17:05 +0200 Subject: [PATCH 2/5] Truncate outgoing payload similar to received for debug logging --- async_substrate_interface/async_substrate.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/async_substrate_interface/async_substrate.py b/async_substrate_interface/async_substrate.py index e06fec0..e799e86 100644 --- a/async_substrate_interface/async_substrate.py +++ b/async_substrate_interface/async_substrate.py @@ -2382,8 +2382,12 @@ async def _make_rpc_request( for payload in payloads: item_id = await ws.send(payload["payload"]) request_manager.add_request(item_id, payload["id"]) + if len(stringified_payload := str(payload)) < 2_000: + output_payload = stringified_payload + else: + output_payload = f"{stringified_payload[:2_000]} (truncated)" logger.debug( - f"Submitted payload ID {payload['id']} with websocket ID {item_id}: {payload}" + f"Submitted payload ID {payload['id']} with websocket ID {item_id}: {output_payload}" ) while True: From a174f1939afa0b92bebb4108389c6212472f3067 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Fri, 26 Sep 2025 21:18:14 +0200 Subject: [PATCH 3/5] Also for sync --- async_substrate_interface/sync_substrate.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/async_substrate_interface/sync_substrate.py b/async_substrate_interface/sync_substrate.py index e4c6c1c..ee1339c 100644 --- a/async_substrate_interface/sync_substrate.py +++ b/async_substrate_interface/sync_substrate.py @@ -1904,8 +1904,12 @@ def _make_rpc_request( raw_websocket_logger.debug(f"WEBSOCKET_SEND> {to_send}") ws.send(to_send) request_manager.add_request(item_id, payload["id"]) + if len(stringified_payload := str(payload)) < 2_000: + output_payload = stringified_payload + else: + output_payload = f"{stringified_payload[:2_000]} (truncated)" logger.debug( - f"Submitted payload ID {payload['id']} with websocket ID {item_id}: {payload}" + f"Submitted payload ID {payload['id']} with websocket ID {item_id}: {output_payload}" ) while True: From c535b38bd4dfa70fe292ca2756799a6b2ded532b Mon Sep 17 00:00:00 2001 From: bdhimes Date: Mon, 29 Sep 2025 17:31:48 +0200 Subject: [PATCH 4/5] Add comment --- async_substrate_interface/async_substrate.py | 2 ++ async_substrate_interface/sync_substrate.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/async_substrate_interface/async_substrate.py b/async_substrate_interface/async_substrate.py index e799e86..2cda046 100644 --- a/async_substrate_interface/async_substrate.py +++ b/async_substrate_interface/async_substrate.py @@ -2382,6 +2382,7 @@ async def _make_rpc_request( for payload in payloads: item_id = await ws.send(payload["payload"]) request_manager.add_request(item_id, payload["id"]) + # truncate to 2000 chars for debug logging if len(stringified_payload := str(payload)) < 2_000: output_payload = stringified_payload else: @@ -2429,6 +2430,7 @@ async def _make_rpc_request( request_manager.add_response( item_id, decoded_response, complete ) + # truncate to 2000 chars for debug logging if ( len(stringified_response := str(decoded_response)) < 2_000 diff --git a/async_substrate_interface/sync_substrate.py b/async_substrate_interface/sync_substrate.py index ee1339c..61efc54 100644 --- a/async_substrate_interface/sync_substrate.py +++ b/async_substrate_interface/sync_substrate.py @@ -1904,6 +1904,7 @@ def _make_rpc_request( raw_websocket_logger.debug(f"WEBSOCKET_SEND> {to_send}") ws.send(to_send) request_manager.add_request(item_id, payload["id"]) + # truncate to 2000 chars for debug logging if len(stringified_payload := str(payload)) < 2_000: output_payload = stringified_payload else: @@ -1972,6 +1973,7 @@ def _make_rpc_request( request_manager.add_response( item_id, decoded_response, complete ) + # truncate to 2000 chars for debug logging if len(stringified_response := str(decoded_response)) < 2_000: output_response = stringified_response # avoids clogging logs up needlessly (esp for Metadata stuff) From 2089eeedb086c2dee48c29299a877ce2c111cec2 Mon Sep 17 00:00:00 2001 From: bdhimes Date: Mon, 6 Oct 2025 15:22:27 +0200 Subject: [PATCH 5/5] Bump version + changelog --- CHANGELOG.md | 5 +++++ pyproject.toml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8226737..9367f78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ # Changelog +## 1.5.5 /2025-10-06 +* Improve timeout task cancellation by @thewhaleking in https://github.com/opentensor/async-substrate-interface/pull/190 + +**Full Changelog**: https://github.com/opentensor/async-substrate-interface/compare/v1.5.4...v1.5.5 + ## 1.5.4 /2025-09-23 * Raw Websocket Logger Inconsistency Fix by @thewhaleking in https://github.com/opentensor/async-substrate-interface/pull/188 diff --git a/pyproject.toml b/pyproject.toml index def7db8..451672d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "async-substrate-interface" -version = "1.5.4" +version = "1.5.5" description = "Asyncio library for interacting with substrate. Mostly API-compatible with py-substrate-interface" readme = "README.md" license = { file = "LICENSE" }