Debounce timeline calendar refresh so it stops pegging the event loop#674
Open
moshemalawach wants to merge 1 commit into
Open
Conversation
The LLM Vision Timeline calendar reloaded the entire events DB on every
SIGNAL_TIMELINE_UPDATED (one per analysed camera event), pinning the asyncio
event loop ('Update of calendar.llm_vision_timeline is taking over 10 seconds')
and starving other integrations.
- calendar.py: route timeline-updated signals through a Debouncer so a burst of
events triggers a single reload; cancel a pending refresh on entity removal.
- timeline.py: drop the redundant load_events() in create_event() whose result
was discarded before _insert_event() reloads.
Adds debounce-wiring tests. Fixes valentinfrlch#673.
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.
Fixes #673.
The timeline calendar reloads the whole events DB every time SIGNAL_TIMELINE_UPDATED fires, and that signal fires once per analysed camera event. On a busy setup this keeps the event loop busy enough that HA logs "Update of calendar.llm_vision_timeline is taking over 10 seconds" over and over, other integrations start timing out (the Frigate API in my case, even though Frigate itself answers fine), and one CPU core sits at 100%. It happens even with a small DB (about 1800 rows here), so it's the refresh frequency and the SQLite contention, not the amount of data.
I confirmed it by sampling per-thread CPU from the host: the main thread (the event loop) is the busy one, and disabling the calendar entity drops it straight back to idle.
What this PR changes:
calendar.py: the timeline-updated signal now goes through a Debouncer with a 1.5s cooldown, so a burst of events triggers a single reload instead of one full DB reload per event. I also added async_will_remove_from_hass to cancel a pending refresh when the entity is removed.
timeline.py: create_event() called await self.load_events() and then threw the result away (nothing reads self.events before the insert, and _insert_event() reloads right after), so I removed that extra full reload.
The calendar still reloads after writes, the reloads just get coalesced.
Tests:
A couple of things I noticed but left out to keep this focused: