Skip to content
This repository was archived by the owner on Jul 6, 2026. It is now read-only.

Commit e2f0781

Browse files
jameshilliardb-rowan
authored andcommitted
Fix race conditions in RPC and web API multicommand methods
Multiple multicommand methods were double-awaiting tasks - first via asyncio.gather() with return_exceptions=True, then calling .result() on the same tasks. This caused ConnectionResetError and other exceptions when connections were lost. Changed to properly use the results from gather() instead of calling .result() on completed tasks, preventing exceptions from being raised after they were already caught. Fixed in: - pyasic/rpc/base.py:144 - RPC _send_split_multicommand - pyasic/web/espminer.py:79 - ESPMiner multicommand - pyasic/web/auradine.py:149 - Auradine multicommand
1 parent 75056cf commit e2f0781

3 files changed

Lines changed: 15 additions & 18 deletions

File tree

pyasic/rpc/base.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,17 +136,16 @@ async def _send_split_multicommand(
136136
self.send_command(cmd, allow_warning=allow_warning)
137137
)
138138

139-
await asyncio.gather(*[tasks[cmd] for cmd in tasks], return_exceptions=True)
139+
results = await asyncio.gather(
140+
*[tasks[cmd] for cmd in tasks], return_exceptions=True
141+
)
140142

141143
data = {}
142-
for cmd in tasks:
143-
try:
144-
result = tasks[cmd].result()
144+
for cmd, result in zip(tasks.keys(), results):
145+
if not isinstance(result, (APIError, Exception)):
145146
if result is None or result == {}:
146147
result = {}
147148
data[cmd] = [result]
148-
except APIError:
149-
pass
150149

151150
return data
152151

pyasic/web/auradine.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,17 +141,16 @@ async def multicommand(
141141
self.send_command(cmd, allow_warning=allow_warning)
142142
)
143143

144-
await asyncio.gather(*[tasks[cmd] for cmd in tasks], return_exceptions=True)
144+
results = await asyncio.gather(
145+
*[tasks[cmd] for cmd in tasks], return_exceptions=True
146+
)
145147

146148
data = {"multicommand": True}
147-
for cmd in tasks:
148-
try:
149-
result = tasks[cmd].result()
149+
for cmd, result in zip(tasks.keys(), results):
150+
if not isinstance(result, (APIError, Exception)):
150151
if result is None or result == {}:
151152
result = {}
152153
data[cmd] = result
153-
except APIError:
154-
pass
155154

156155
return data
157156

pyasic/web/espminer.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,16 @@ async def multicommand(
7171
self.send_command(cmd, allow_warning=allow_warning)
7272
)
7373

74-
await asyncio.gather(*[tasks[cmd] for cmd in tasks], return_exceptions=True)
74+
results = await asyncio.gather(
75+
*[tasks[cmd] for cmd in tasks], return_exceptions=True
76+
)
7577

7678
data = {"multicommand": True}
77-
for cmd in tasks:
78-
try:
79-
result = tasks[cmd].result()
79+
for cmd, result in zip(tasks.keys(), results):
80+
if not isinstance(result, (APIError, Exception)):
8081
if result is None or result == {}:
8182
result = {}
8283
data[cmd] = result
83-
except APIError:
84-
pass
8584

8685
return data
8786

0 commit comments

Comments
 (0)