klippy_apis: fix blocking issue in start_print and do_restart

The "wait_connected" method would block indefinitely until a klippy
connection is established.  This isn't the behavior we want, we only
want to wait "if" a connection has been established until Klippy
reports that its startup sequence is complete.

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Eric Callahan 2022-02-22 14:34:14 -05:00
parent 86469903f3
commit 2b1a3e5603
2 changed files with 14 additions and 5 deletions

View File

@ -107,23 +107,24 @@ class KlippyAPI(Subscribable):
# WARNING: Do not call this method from within the following
# event handlers:
# klippy_identified, klippy_started, klippy_ready, klippy_disconnect
# Doing so will result in a deadlock
# Doing so will result in "wait_started" blocking for the specifed
# timeout (default 20s) and returning False.
# XXX - validate that file is on disk
if filename[0] == '/':
filename = filename[1:]
# Escape existing double quotes in the file name
filename = filename.replace("\"", "\\\"")
script = f'SDCARD_PRINT_FILE FILENAME="{filename}"'
await self.klippy.wait_connected()
await self.klippy.wait_started()
return await self.run_gcode(script)
async def do_restart(self, gc: str) -> str:
# WARNING: Do not call this method from within the following
# event handlers:
# klippy_identified, klippy_started, klippy_ready, klippy_disconnect
# Doing so will result in a deadlock
# XXX - validate that file is on disk
await self.klippy.wait_connected()
# Doing so will result in "wait_started" blocking for the specifed
# timeout (default 20s) and returning False.
await self.klippy.wait_started()
try:
result = await self.run_gcode(gc)
except self.server.error as e:

View File

@ -100,6 +100,14 @@ class KlippyConnection:
pass
return self.is_connected()
async def wait_started(self, timeout: float = 20.) -> bool:
if self.connection_task is None or not self.is_connected():
return False
if not self.connection_task.done():
await asyncio.wait_for(
asyncio.shield(self.connection_task), timeout=timeout)
return self.is_connected()
async def _read_stream(self, reader: asyncio.StreamReader) -> None:
errors_remaining: int = 10
while not reader.at_eof():