Fix statistics doing I/O in the event loop (#68315)

This commit is contained in:
J. Nick Koston 2022-03-18 00:49:11 -10:00 committed by GitHub
parent 9215702388
commit b284eddc63
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -12,6 +12,7 @@ from typing import Any, Literal, cast
import voluptuous as vol import voluptuous as vol
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
from homeassistant.components.recorder import get_instance
from homeassistant.components.recorder.models import StateAttributes, States from homeassistant.components.recorder.models import StateAttributes, States
from homeassistant.components.recorder.util import execute, session_scope from homeassistant.components.recorder.util import execute, session_scope
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
@ -470,17 +471,8 @@ class StatisticsSensor(SensorEntity):
self.hass, _scheduled_update, next_to_purge_timestamp self.hass, _scheduled_update, next_to_purge_timestamp
) )
async def _initialize_from_database(self) -> None: def _fetch_states_from_database(self) -> list[State]:
"""Initialize the list of states from the database. """Fetch the states from the database."""
The query will get the list of states in DESCENDING order so that we
can limit the result to self._sample_size. Afterwards reverse the
list so that we get it in the right order again.
If MaxAge is provided then query will restrict to entries younger then
current datetime - MaxAge.
"""
_LOGGER.debug("%s: initializing values from the database", self.entity_id) _LOGGER.debug("%s: initializing values from the database", self.entity_id)
states = [] states = []
@ -512,8 +504,21 @@ class StatisticsSensor(SensorEntity):
if not native.attributes: if not native.attributes:
native.attributes = attributes.to_native() native.attributes = attributes.to_native()
states.append(native) states.append(native)
return states
if states: async def _initialize_from_database(self) -> None:
"""Initialize the list of states from the database.
The query will get the list of states in DESCENDING order so that we
can limit the result to self._sample_size. Afterwards reverse the
list so that we get it in the right order again.
If MaxAge is provided then query will restrict to entries younger then
current datetime - MaxAge.
"""
if states := await get_instance(self.hass).async_add_executor_job(
self._fetch_states_from_database
):
for state in reversed(states): for state in reversed(states):
self._add_state_to_queue(state) self._add_state_to_queue(state)