perf: parallelize the TURN OFF button via shared _shutdown_devices
shutdown_all() was the only remaining sequential shutdown path (TV, then
Gabi, then Gaja — 10+s with SSH timeouts). It now uses the same parallel
_shutdown_devices() as the budget tick, which gained a {dev_id: result}
return value so the button response keeps per-device details and
registry ordering. Per-device failures are isolated instead of being
silently swallowed.
This commit is contained in:
29
devices.py
29
devices.py
@ -278,12 +278,25 @@ def curfew_status() -> dict:
|
||||
}
|
||||
|
||||
|
||||
def _shutdown_devices(device_ids: list[str]):
|
||||
"""Shut down a list of devices in parallel."""
|
||||
def _shutdown_devices(device_ids: list[str]) -> dict[str, dict | None]:
|
||||
"""Shut down a list of devices in parallel.
|
||||
|
||||
Returns {dev_id: turnoff result or None on failure}.
|
||||
"""
|
||||
results: dict[str, dict | None] = {}
|
||||
if not device_ids:
|
||||
return
|
||||
return results
|
||||
with ThreadPoolExecutor(max_workers=len(device_ids)) as executor:
|
||||
list(executor.submit(DEVICES[dev_id]["turnoff"]) for dev_id in device_ids)
|
||||
futures = {
|
||||
executor.submit(DEVICES[dev_id]["turnoff"]): dev_id
|
||||
for dev_id in device_ids
|
||||
}
|
||||
for future, dev_id in futures.items():
|
||||
try:
|
||||
results[dev_id] = future.result()
|
||||
except Exception:
|
||||
results[dev_id] = None
|
||||
return results
|
||||
|
||||
|
||||
# ── Budget timer (runs every 10s in background) ──────────────────────
|
||||
@ -415,10 +428,14 @@ def stop_timer():
|
||||
# ── Orchestrator ──────────────────────────────────────────────────────
|
||||
|
||||
def shutdown_all() -> list[dict]:
|
||||
"""Indiscriminately turn off all devices. Returns ordered list of action dicts."""
|
||||
"""Indiscriminately turn off all devices in parallel.
|
||||
|
||||
Returns ordered list of action dicts (registry order).
|
||||
"""
|
||||
results = _shutdown_devices(list(DEVICES))
|
||||
actions = []
|
||||
for dev_id, dev_info in DEVICES.items():
|
||||
result = dev_info["turnoff"]()
|
||||
result = results.get(dev_id)
|
||||
if result:
|
||||
budget_minutes = _budget_to_minutes(_get_budget(dev_id))
|
||||
actions.append({
|
||||
|
||||
Reference in New Issue
Block a user