Make light polling and transition cleanup idempotent - #692
Conversation
a6f223e to
cb6dd2f
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #692 +/- ##
=======================================
Coverage 97.19% 97.19%
=======================================
Files 57 57
Lines 10560 10567 +7
=======================================
+ Hits 10264 10271 +7
Misses 296 296 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
cbdd2f8 to
d1aa5c3
Compare
There was a problem hiding this comment.
🟢 Approval recommended
Changes are narrowly scoped, address the described resource-tracking bugs directly, and are backed by targeted regression tests.
Pull request overview
This PR fixes idempotency issues in the light platform’s background refresh polling and transition timer cleanup, preventing orphaned tasks/handles when enabling/disabling lights repeatedly and ensuring tracked resources are correctly removed.
Changes:
- Make
start_polling()idempotent by reusing an active refresh task and removing completed tasks from_tracked_tasksbefore replacement. - Fix transition listener cleanup by removing the original timer handle from
_tracked_handlesbefore clearing_transition_listener. - Add regression tests covering repeated enable/disable, completed-task replacement, and transition timer unsubscription.
File summaries
| File | Description |
|---|---|
zha/application/platforms/light/__init__.py |
Ensures refresh polling tasks and transition timer handles are cleaned up deterministically and don’t become orphaned on repeated operations. |
tests/test_light.py |
Adds regression coverage for repeated enable/disable behavior and correct task/handle tracking cleanup. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Repeatedly enabling a light starts another refresh task and loses the handle used by
disable(). Transition cleanup also clears_transition_listenerbefore trying to remove that handle from_tracked_handles, retaining cancelled timers.Keep the active polling task, discard a completed task before replacement, and remove the original transition handle before clearing it. Regression tests cover repeated enable/disable, completed-task replacement, and timer unsubscription.
Validation against
devat66603431339afe37fa0048b70ff31d77dceb8f95: Python 3.12 full suite, 1385 passed, coverage above the 95% project gate; full pre-commit (codespell, Ruff, formatting, mypy, lock check) passed. Relevant regression checks fail on the unchanged base. GitHub CI for Python 3.12/3.13/3.14 is reported separately on the PR.