From 85649ec589222267a94add00df28095a739f97b8 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 11 Feb 2023 22:21:16 -0600 Subject: [PATCH] Reduce overhead to see if an entity is recorded (#87912) A significant chunk of list_statistic_ids was checking if the entity was recorded because it had to get the recorder instance over and over --- homeassistant/components/recorder/core.py | 3 +++ homeassistant/components/sensor/recorder.py | 10 ++++++---- tests/components/sensor/test_recorder.py | 12 ++++++++---- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/homeassistant/components/recorder/core.py b/homeassistant/components/recorder/core.py index 2193a219fa5..a8f00ca5ba0 100644 --- a/homeassistant/components/recorder/core.py +++ b/homeassistant/components/recorder/core.py @@ -185,6 +185,9 @@ class Recorder(threading.Thread): self.engine: Engine | None = None self.run_history = RunHistory() + # The entity_filter is exposed on the recorder instance so that + # it can be used to see if an entity is being recorded and is called + # by is_entity_recorder and the sensor recorder. self.entity_filter = entity_filter self.exclude_t = set(exclude_t) diff --git a/homeassistant/components/sensor/recorder.py b/homeassistant/components/sensor/recorder.py index 8863d5dfaa0..e2790464fe6 100644 --- a/homeassistant/components/sensor/recorder.py +++ b/homeassistant/components/sensor/recorder.py @@ -13,8 +13,8 @@ from sqlalchemy.orm.session import Session from homeassistant.components.recorder import ( DOMAIN as RECORDER_DOMAIN, + get_instance, history, - is_entity_recorded, statistics, util as recorder_util, ) @@ -76,9 +76,10 @@ def _get_sensor_states(hass: HomeAssistant) -> list[State]: """Get the current state of all sensors for which to compile statistics.""" all_sensors = hass.states.all(DOMAIN) statistics_sensors = [] + instance = get_instance(hass) for state in all_sensors: - if not is_entity_recorded(hass, state.entity_id): + if not instance.entity_filter(state.entity_id): continue if not try_parse_enum(SensorStateClass, state.attributes.get(ATTR_STATE_CLASS)): continue @@ -680,6 +681,7 @@ def validate_statistics( metadatas = statistics.get_metadata(hass, statistic_source=RECORDER_DOMAIN) sensor_entity_ids = {i.entity_id for i in sensor_states} sensor_statistic_ids = set(metadatas) + instance = get_instance(hass) for state in sensor_states: entity_id = state.entity_id @@ -689,7 +691,7 @@ def validate_statistics( state_unit = state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) if metadata := metadatas.get(entity_id): - if not is_entity_recorded(hass, state.entity_id): + if not instance.entity_filter(state.entity_id): # Sensor was previously recorded, but no longer is validation_result[entity_id].append( statistics.ValidationIssue( @@ -739,7 +741,7 @@ def validate_statistics( ) ) elif state_class is not None: - if not is_entity_recorded(hass, state.entity_id): + if not instance.entity_filter(state.entity_id): # Sensor is not recorded validation_result[entity_id].append( statistics.ValidationIssue( diff --git a/tests/components/sensor/test_recorder.py b/tests/components/sensor/test_recorder.py index 710c08e7822..5eee2175626 100644 --- a/tests/components/sensor/test_recorder.py +++ b/tests/components/sensor/test_recorder.py @@ -3894,8 +3894,10 @@ async def test_validate_statistics_sensor_no_longer_recorded( } ], } - with patch( - "homeassistant.components.sensor.recorder.is_entity_recorded", + instance = get_instance(hass) + with patch.object( + instance, + "entity_filter", return_value=False, ): await assert_validation_result(client, expected) @@ -3945,8 +3947,10 @@ async def test_validate_statistics_sensor_not_recorded( } ], } - with patch( - "homeassistant.components.sensor.recorder.is_entity_recorded", + instance = get_instance(hass) + with patch.object( + instance, + "entity_filter", return_value=False, ): hass.states.async_set("sensor.test", 10, attributes=attributes)