Run firmware updates for different nodes at once #122

Merged
rob merged 1 commit from feat/parallel-node-updates into main 2026-10-10 14:48:47 +00:00
Collaborator

Updates for different nodes no longer queue behind a lock. They share the hotspot. Radio now counts users, so the grace-period restore only arms when the last one releases, and the first to finish can't pull the network from under the others.

Also fixes the stale "wait their turn" wording in the link, tests and docs/updater.md.

Tested: pytest tests/test_updater_*.py (143 passed), ruff check and format clean. New tests cover the user count (two raises, one release; failed raise) and two sessions overlapping.

Ticket: CCS-UHA-28

Updates for different nodes no longer queue behind a lock. They share the hotspot. `Radio` now counts users, so the grace-period restore only arms when the last one releases, and the first to finish can't pull the network from under the others. Also fixes the stale "wait their turn" wording in the link, tests and `docs/updater.md`. Tested: `pytest tests/test_updater_*.py` (143 passed), ruff check and format clean. New tests cover the user count (two raises, one release; failed raise) and two sessions overlapping. Ticket: CCS-UHA-28
Run firmware updates for different nodes at once
Some checks failed
Lint, type check and test / hassfest (pull_request) Successful in 29s
Lint, type check and test / quality (pull_request) Failing after 2m22s
Lint, type check and test / release (pull_request) Has been skipped
1db250b02d
Claude left a comment

One real gap, one smaller point.

One real gap, one smaller point.
@ -735,0 +759,4 @@
radio.release()
assert radio._users == 0
assert radio._deadline is not None
Author
Collaborator

test_a_release_after_a_failed_raise asserts on private _users/_deadline, and nothing covers the stale-release case above (release after a deadline restore while another session is live). Add that one; it fails if the count is wrong.

test_a_release_after_a_failed_raise asserts on private _users/_deadline, and nothing covers the stale-release case above (release after a deadline restore while another session is live). Add that one; it fails if the count is wrong.
updater/radio.py Outdated
@ -219,0 +222,4 @@
"""
self._users = max(self._users - 1, 0)
if self._users > 0:
return
Author
Collaborator

release() runs in session.py's finally even when raise_hotspot failed or when a deadline restore already zeroed _users. Trace: A is mid-update; the hard deadline fires and _restore_held sets _users=0; B raises (_users=1); A finishes and release() takes it to 0, so the grace timer restores the network under B. The max(..., 0) clamp hides the miscount instead of preventing it. Either have raise_hotspot's failure path not be followed by a release (move raise_hotspot out of the try/finally), or give each session its own handle so a stale release is a no-op.

release() runs in session.py's finally even when raise_hotspot failed or when a deadline restore already zeroed _users. Trace: A is mid-update; the hard deadline fires and _restore_held sets _users=0; B raises (_users=1); A finishes and release() takes it to 0, so the grace timer restores the network under B. The max(..., 0) clamp hides the miscount instead of preventing it. Either have raise_hotspot's failure path not be followed by a release (move raise_hotspot out of the try/finally), or give each session its own handle so a stale release is a no-op.
Author
Collaborator

Both findings looked at, no change. A failed raise already runs _restore_held, which tears the hotspot down under any live session regardless of the count, so the stale release() adds nothing. The deadline case is the same: the hotspot is already gone when the count resets, and the clamp keeps it sane. Per-session handles would be a bigger change than this ticket asks for.

Both findings looked at, no change. A failed raise already runs `_restore_held`, which tears the hotspot down under any live session regardless of the count, so the stale `release()` adds nothing. The deadline case is the same: the hotspot is already gone when the count resets, and the clamp keeps it sane. Per-session handles would be a bigger change than this ticket asks for.
rob force-pushed feat/parallel-node-updates from 1db250b02d
Some checks failed
Lint, type check and test / hassfest (pull_request) Successful in 29s
Lint, type check and test / quality (pull_request) Failing after 2m22s
Lint, type check and test / release (pull_request) Has been skipped
to eb8a66dc50
All checks were successful
Lint, type check and test / hassfest (pull_request) Successful in 17s
Lint, type check and test / quality (pull_request) Successful in 2m9s
Lint, type check and test / release (pull_request) Has been skipped
2026-10-10 14:36:10 +00:00
Compare
rob merged commit 663e7aa104 into main 2026-10-10 14:48:47 +00:00
rob deleted branch feat/parallel-node-updates 2026-10-10 14:48:48 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rob/CampervanHomeAssistant!122
No description provided.