Skip to content

Commit f9c6228

Browse files
committed
We occasionally get incorrect timeouts with AsyncSubstrateInterface, and this is largely due to the calculation of time — loop.time() is not necessarily time.time()
1 parent 83acb8c commit f9c6228

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

async_substrate_interface/async_substrate.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -531,13 +531,21 @@ def __init__(
531531
self._open_subscriptions = 0
532532
self._options = options if options else {}
533533
self.last_received = time.time()
534+
self.last_sent = time.time()
534535

535536
async def __aenter__(self):
536537
async with self._lock:
537538
self._in_use += 1
538539
await self.connect()
540+
now = asyncio.get_running_loop().time()
541+
self.last_received = now
542+
self.last_sent = now
539543
return self
540544

545+
@staticmethod
546+
async def loop_time() -> float:
547+
return asyncio.get_running_loop().time()
548+
541549
async def connect(self, force=False):
542550
if self._exit_task:
543551
self._exit_task.cancel()
@@ -594,7 +602,7 @@ async def _recv(self) -> None:
594602
try:
595603
# TODO consider wrapping this in asyncio.wait_for and use that for the timeout logic
596604
response = json.loads(await self.ws.recv(decode=False))
597-
self.last_received = time.time()
605+
self.last_received = await self.loop_time()
598606
async with self._lock:
599607
# note that these 'subscriptions' are all waiting sent messages which have not received
600608
# responses, and thus are not the same as RPC 'subscriptions', which are unique
@@ -630,12 +638,12 @@ async def send(self, payload: dict) -> int:
630638
Returns:
631639
id: the internal ID of the request (incremented int)
632640
"""
633-
# async with self._lock:
634641
original_id = get_next_id()
635642
# self._open_subscriptions += 1
636643
await self.max_subscriptions.acquire()
637644
try:
638645
await self.ws.send(json.dumps({**payload, **{"id": original_id}}))
646+
self.last_sent = await self.loop_time()
639647
return original_id
640648
except (ConnectionClosed, ssl.SSLError, EOFError):
641649
async with self._lock:
@@ -2120,7 +2128,11 @@ async def _make_rpc_request(
21202128

21212129
if request_manager.is_complete:
21222130
break
2123-
if time.time() - self.ws.last_received >= self.retry_timeout:
2131+
if (
2132+
(current_time := await self.ws.loop_time()) - self.ws.last_received
2133+
>= self.retry_timeout
2134+
and current_time - self.ws.last_sent >= self.retry_timeout
2135+
):
21242136
if attempt >= self.max_retries:
21252137
logger.warning(
21262138
f"Timed out waiting for RPC requests {attempt} times. Exiting."

0 commit comments

Comments
 (0)