Disconnect at once after restart, reboot, quit or hibernate

The device goes down without answering, so the editor waited out the 30 s
Sox timeout before dropping the session. The invoke now waits 3 s (time for
DASP to resend it once) and the editor disconnects either way; an error
reply from the device is still reported and keeps the connection. Covers the
App right-click actions and the restart Put with Files offers.

- sox: request/requests/invoke take a timeout

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-11 10:42:36 +03:00
co-authored by Claude Opus 5.5
parent e070bd0f1e
commit f2b18923b7
3 changed files with 26 additions and 17 deletions
+16 -7
View File
@@ -617,27 +617,35 @@ def _invoke_app_action(slot_name):
if slot is None:
app_state.set_status(f"Action slot '{slot_name}' not found on app", warn=True)
return False
goes_down = slot_name in ("hibernate", "quit", "restart", "reboot")
goes_down = slot_name in _GOES_DOWN
try:
ds.sox_client.invoke(0, slot["id"])
app_state.set_status(f"Invoked '{slot_name}' on device")
# A device going down often does so before it answers: give the request a few
# seconds (time for DASP to resend it once), then disconnect either way rather
# than wait for the session to drop.
ds.sox_client.invoke(0, slot["id"], timeout=_GOES_DOWN_WAIT if goes_down else 30.0)
except sox.SoxException as e:
# A P-ION restarts before it answers: no reply is what a restart looks like.
if not (goes_down and "timeout" in str(e).lower()):
refused = "timeout" not in str(e).lower() and "closed" not in str(e).lower()
if not goes_down or refused:
app_state.set_status(f"Invoke '{slot_name}' failed: {e}", warn=True)
return False
app_state.set_status(f"Invoked '{slot_name}'; the device went down without replying")
except Exception as e:
app_state.set_status(f"Invoke '{slot_name}' failed: {e}", warn=True)
return False
if slot_name == "save":
app_state.mark_clean()
app_state.set_status(f"Invoked '{slot_name}' on device")
elif goes_down:
host = app_state.device_host
do_device_disconnect()
app_state.set_status(f"Sent '{slot_name}' to {host} and disconnected")
else:
app_state.set_status(f"Invoked '{slot_name}' on device")
return True
_APP_ACTIONS = ["save", "hibernate", "quit", "restart", "reboot"]
_GOES_DOWN = ("hibernate", "quit", "restart", "reboot") # the device stops answering
_GOES_DOWN_WAIT = 3.0 # seconds to wait for its reply before disconnecting
def do_get_with_file():
@@ -871,7 +879,8 @@ def do_put_with_files():
f"{len(plan.app_files) + len(plan.media)} files written to the device."
f"{NL}{NL}Restart the device now to complete provisioning?"):
if _invoke_app_action("restart"):
app_state.set_status(f"Put {os.path.basename(path)}; the device is restarting")
app_state.set_status(f"Put {os.path.basename(path)}; the device is "
"restarting, disconnected")
_run_with_progress("Put with Files", prepare, planned)