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]):
|
def _shutdown_devices(device_ids: list[str]) -> dict[str, dict | None]:
|
||||||
"""Shut down a list of devices in parallel."""
|
"""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:
|
if not device_ids:
|
||||||
return
|
return results
|
||||||
with ThreadPoolExecutor(max_workers=len(device_ids)) as executor:
|
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) ──────────────────────
|
# ── Budget timer (runs every 10s in background) ──────────────────────
|
||||||
@ -415,10 +428,14 @@ def stop_timer():
|
|||||||
# ── Orchestrator ──────────────────────────────────────────────────────
|
# ── Orchestrator ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
def shutdown_all() -> list[dict]:
|
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 = []
|
actions = []
|
||||||
for dev_id, dev_info in DEVICES.items():
|
for dev_id, dev_info in DEVICES.items():
|
||||||
result = dev_info["turnoff"]()
|
result = results.get(dev_id)
|
||||||
if result:
|
if result:
|
||||||
budget_minutes = _budget_to_minutes(_get_budget(dev_id))
|
budget_minutes = _budget_to_minutes(_get_budget(dev_id))
|
||||||
actions.append({
|
actions.append({
|
||||||
|
|||||||
Reference in New Issue
Block a user