Fix poll coroutine growth#1739
Merged
AlexxIT merged 3 commits intoMar 2, 2026
Merged
Conversation
AlexxIT
approved these changes
Mar 2, 2026
Owner
|
Thanks! I simplified the code a little and removed the clearing of old tasks. They will be replaced with new ones anyway. I think all the logic is preserved. I don't have any real devices to test it on. PS. How you found this error is amazing! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Commits
Issue
XRegistry.run_forever() schedules fire-and-forget cloud uiActive updates every 30s for several UIIDs.
But XRegistryCloud.send() globally rate-limits any uiActive payload to 1 per second (last_ui_active shared across all devices).
If the site has >30 cloud-polled uiActive devices, production rate > service rate:
That creates a queue that grows forever. Over days, thousands of pending send() coroutines accumulate and keep sleeping/waking, causes severe HA Core responsiveness degradation.
For example:
How to reproduce
uiActive) and cannot update via LAN.After several days of uptime, Home Assistant Core responsiveness gradually degrades (slow UI/API responses and delayed service execution) due to accumulation of pending cloud
uiActiverefresh tasks.Fix
This change deduplicates the periodic cloud uiActive refresh per device, so each device can have at most one pending/in-flight uiActive refresh task at a time.
To keep the change minimal, it does not alter user-initiated command behavior. Normal cloud commands (e.g. turn_on/turn_off) will still queue indiscriminately and command rate could exceed cloud send capacity; this fix specifically prevents unbounded backlog growth from the periodic uiActive refresh scheduler. The original throttling behaviour in
XRegistryCloud.send()also remains unchanged.Profiling evidence
Production HA with 44 sonoff switches, captured for 60s with
profiler.start.Before fix (degraded state after a few days) vs post-restart baseline:
custom_components/sonoff/core/ewelink/cloud.py:sendasyncio.sleepasyncio scheduler churn:
asyncio.events.__lt__: 43,075 → 4,470,033 (~104x)call_later: 3,866 → 322,541 (~83x)call_at: 4,012 → 322,663 (~80x)_call_soon: 4,562 → 323,746 (~71x)Post-fix profiling (production HA after third day):
cloud.py:send: 1,694 calls / 60s (down from 322,243 degraded)asyncio.sleep: 4,328 (down from 645,058 degraded)asyncio.events.__lt__: 24,132 (was 4,470,033 degraded)call_later: 2,166 (was 322,541 degraded)call_at: 2,283 (was 322,663 degraded)_call_soon: 2,845 (was 323,746 degraded)After applying this patch, the runaway pattern disappeared in production profiling (same 60s
profiler.startcapture).Tests