Avoid reschedule churn in Storage.async_delay_save (#111091)

* Avoid circular import in Storage.async_delay_save

We call Storage.async_delay_save for every entity being added or removed
from the registry. The late import took more time than everything else
in the function.

* Avoid reschedule churn in Storage.async_delay_save

When we are adding or removing entities we will call async_delay_save
quite often which has to add and remove a TimerHandle on the event loop
which can add up when there are a lot of registry items changing.

If the timer handle still has 80% of the time remaining on it
we will avoid resceduling and let it fire at the time the
original async_delay_save call was made. This ensures we
do not force the event loop to rebuild its heapq because
too many timer handlers were cancelled at once

* div0

* add coverage for 0 since we had none

* fix bad conflict

* tweaks

* tweaks

* tweaks

* tweaks

* tweaks

* tweaks

* more test fixes

* mqtt tests rely on event loop overhead
This commit is contained in:
J. Nick Koston
2024-02-23 21:46:00 -10:00
committed by GitHub
parent ff0e0b3e77
commit 5b8591ec7e
5 changed files with 149 additions and 18 deletions

View File

@@ -1,10 +1,10 @@
"""The tests for Home Assistant frontend."""
from datetime import timedelta
from http import HTTPStatus
import re
from typing import Any
from unittest.mock import patch
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.frontend import (
@@ -20,7 +20,6 @@ from homeassistant.components.websocket_api.const import TYPE_RESULT
from homeassistant.core import HomeAssistant
from homeassistant.loader import async_get_integration
from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util
from tests.common import MockUser, async_capture_events, async_fire_time_changed
from tests.typing import MockHAClientWebSocket, WebSocketGenerator
@@ -220,7 +219,10 @@ async def test_themes_persist(
async def test_themes_save_storage(
hass: HomeAssistant, hass_storage: dict[str, Any], frontend_themes
hass: HomeAssistant,
hass_storage: dict[str, Any],
freezer: FrozenDateTimeFactory,
frontend_themes,
) -> None:
"""Test that theme settings are restores after restart."""
@@ -233,7 +235,8 @@ async def test_themes_save_storage(
)
# To trigger the call_later
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=60))
freezer.tick(60.0)
async_fire_time_changed(hass)
# To execute the save
await hass.async_block_till_done()