Rename recorder run_history to table_managers.recorder_runs_manager (#90070)
parent
1439a3d572
commit
96225bb287
|
@ -80,9 +80,9 @@ from .queries import (
|
|||
has_events_context_ids_to_migrate,
|
||||
has_states_context_ids_to_migrate,
|
||||
)
|
||||
from .run_history import RunHistory
|
||||
from .table_managers.event_data import EventDataManager
|
||||
from .table_managers.event_types import EventTypeManager
|
||||
from .table_managers.recorder_runs import RecorderRunsManager
|
||||
from .table_managers.state_attributes import StateAttributesManager
|
||||
from .table_managers.states import StatesManager
|
||||
from .table_managers.states_meta import StatesMetaManager
|
||||
|
@ -198,7 +198,6 @@ class Recorder(threading.Thread):
|
|||
self.async_recorder_ready = asyncio.Event()
|
||||
self._queue_watch = threading.Event()
|
||||
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
|
||||
|
@ -208,6 +207,8 @@ class Recorder(threading.Thread):
|
|||
|
||||
self.schema_version = 0
|
||||
self._commits_without_expire = 0
|
||||
|
||||
self.recorder_runs_manager = RecorderRunsManager()
|
||||
self.states_manager = StatesManager()
|
||||
self.event_data_manager = EventDataManager(self)
|
||||
self.event_type_manager = EventTypeManager(self)
|
||||
|
@ -216,6 +217,7 @@ class Recorder(threading.Thread):
|
|||
self, exclude_attributes_by_domain
|
||||
)
|
||||
self.statistics_meta_manager = StatisticsMetaManager(self)
|
||||
|
||||
self.event_session: Session | None = None
|
||||
self._get_session: Callable[[], Session] | None = None
|
||||
self._completed_first_database_setup: bool | None = None
|
||||
|
@ -1117,7 +1119,7 @@ class Recorder(threading.Thread):
|
|||
finally:
|
||||
self._close_connection()
|
||||
move_away_broken_database(dburl_to_path(self.db_url))
|
||||
self.run_history.reset()
|
||||
self.recorder_runs_manager.reset()
|
||||
self._setup_recorder()
|
||||
self._setup_run()
|
||||
|
||||
|
@ -1333,8 +1335,8 @@ class Recorder(threading.Thread):
|
|||
def _setup_run(self) -> None:
|
||||
"""Log the start of the current run and schedule any needed jobs."""
|
||||
with session_scope(session=self.get_session()) as session:
|
||||
end_incomplete_runs(session, self.run_history.recording_start)
|
||||
self.run_history.start(session)
|
||||
end_incomplete_runs(session, self.recorder_runs_manager.recording_start)
|
||||
self.recorder_runs_manager.start(session)
|
||||
|
||||
self._open_event_session()
|
||||
|
||||
|
@ -1346,15 +1348,15 @@ class Recorder(threading.Thread):
|
|||
"""End the recorder session."""
|
||||
if self.event_session is None:
|
||||
return
|
||||
if self.run_history.active:
|
||||
self.run_history.end(self.event_session)
|
||||
if self.recorder_runs_manager.active:
|
||||
self.recorder_runs_manager.end(self.event_session)
|
||||
try:
|
||||
self._commit_event_session_or_retry()
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Error saving the event session during shutdown: %s", err)
|
||||
|
||||
self.event_session.close()
|
||||
self.run_history.clear()
|
||||
self.recorder_runs_manager.clear()
|
||||
|
||||
def _shutdown(self) -> None:
|
||||
"""Save end time for current run."""
|
||||
|
|
|
@ -742,7 +742,7 @@ def _get_rows_with_session(
|
|||
)
|
||||
|
||||
if run is None:
|
||||
run = recorder.get_instance(hass).run_history.get(utc_point_in_time)
|
||||
run = recorder.get_instance(hass).recorder_runs_manager.get(utc_point_in_time)
|
||||
|
||||
if run is None or process_timestamp(run.start) > utc_point_in_time:
|
||||
# History did not run before utc_point_in_time
|
||||
|
|
|
@ -577,7 +577,7 @@ def _get_rows_with_session(
|
|||
)
|
||||
|
||||
if run is None:
|
||||
run = recorder.get_instance(hass).run_history.get(utc_point_in_time)
|
||||
run = recorder.get_instance(hass).recorder_runs_manager.get(utc_point_in_time)
|
||||
|
||||
if run is None or process_timestamp(run.start) > utc_point_in_time:
|
||||
# History did not run before utc_point_in_time
|
||||
|
|
|
@ -517,7 +517,9 @@ def _purge_old_recorder_runs(
|
|||
"""Purge all old recorder runs."""
|
||||
# Recorder runs is small, no need to batch run it
|
||||
deleted_rows = session.execute(
|
||||
delete_recorder_runs_rows(purge_before, instance.run_history.current.run_id)
|
||||
delete_recorder_runs_rows(
|
||||
purge_before, instance.recorder_runs_manager.current.run_id
|
||||
)
|
||||
)
|
||||
_LOGGER.debug("Deleted %s recorder_runs", deleted_rows)
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ async def system_health_info(hass: HomeAssistant) -> dict[str, Any]:
|
|||
"""Get info for the info page."""
|
||||
instance = get_instance(hass)
|
||||
|
||||
run_history = instance.run_history
|
||||
recorder_runs_manager = instance.recorder_runs_manager
|
||||
database_name = urlparse(instance.db_url).path.lstrip("/")
|
||||
db_engine_info = _async_get_db_engine_info(instance)
|
||||
db_stats: dict[str, Any] = {}
|
||||
|
@ -68,7 +68,7 @@ async def system_health_info(hass: HomeAssistant) -> dict[str, Any]:
|
|||
_get_db_stats, instance, database_name
|
||||
)
|
||||
db_runs = {
|
||||
"oldest_recorder_run": run_history.first.start,
|
||||
"current_recorder_run": run_history.current.start,
|
||||
"oldest_recorder_run": recorder_runs_manager.first.start,
|
||||
"current_recorder_run": recorder_runs_manager.current.start,
|
||||
}
|
||||
return db_runs | db_stats | db_engine_info
|
||||
|
|
|
@ -9,8 +9,8 @@ from sqlalchemy.orm.session import Session
|
|||
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from .db_schema import RecorderRuns
|
||||
from .models import process_timestamp
|
||||
from ..db_schema import RecorderRuns
|
||||
from ..models import process_timestamp
|
||||
|
||||
|
||||
def _find_recorder_run_for_start_time(
|
||||
|
@ -40,7 +40,7 @@ class _RecorderRunsHistory:
|
|||
runs_by_timestamp: dict[int, RecorderRuns]
|
||||
|
||||
|
||||
class RunHistory:
|
||||
class RecorderRunsManager:
|
||||
"""Track recorder run history."""
|
||||
|
||||
def __init__(self) -> None:
|
|
@ -113,7 +113,7 @@ class PurgeTask(RecorderTask):
|
|||
instance, self.purge_before, self.repack, self.apply_filter
|
||||
):
|
||||
with instance.get_session() as session:
|
||||
instance.run_history.load_from_db(session)
|
||||
instance.recorder_runs_manager.load_from_db(session)
|
||||
# We always need to do the db cleanups after a purge
|
||||
# is finished to ensure the WAL checkpoint and other
|
||||
# tasks happen after a vacuum.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
"""Test run history."""
|
||||
"""Test recorder runs table manager."""
|
||||
from datetime import timedelta
|
||||
from unittest.mock import patch
|
||||
|
||||
|
@ -25,29 +25,35 @@ async def test_run_history(recorder_mock: Recorder, hass: HomeAssistant) -> None
|
|||
session.add(RecorderRuns(start=two_days_ago, created=two_days_ago))
|
||||
session.add(RecorderRuns(start=one_day_ago, created=one_day_ago))
|
||||
session.commit()
|
||||
instance.run_history.load_from_db(session)
|
||||
instance.recorder_runs_manager.load_from_db(session)
|
||||
|
||||
assert (
|
||||
process_timestamp(
|
||||
instance.run_history.get(three_days_ago + timedelta(microseconds=1)).start
|
||||
instance.recorder_runs_manager.get(
|
||||
three_days_ago + timedelta(microseconds=1)
|
||||
).start
|
||||
)
|
||||
== three_days_ago
|
||||
)
|
||||
assert (
|
||||
process_timestamp(
|
||||
instance.run_history.get(two_days_ago + timedelta(microseconds=1)).start
|
||||
instance.recorder_runs_manager.get(
|
||||
two_days_ago + timedelta(microseconds=1)
|
||||
).start
|
||||
)
|
||||
== two_days_ago
|
||||
)
|
||||
assert (
|
||||
process_timestamp(
|
||||
instance.run_history.get(one_day_ago + timedelta(microseconds=1)).start
|
||||
instance.recorder_runs_manager.get(
|
||||
one_day_ago + timedelta(microseconds=1)
|
||||
).start
|
||||
)
|
||||
== one_day_ago
|
||||
)
|
||||
assert (
|
||||
process_timestamp(instance.run_history.get(now).start)
|
||||
== instance.run_history.recording_start
|
||||
process_timestamp(instance.recorder_runs_manager.get(now).start)
|
||||
== instance.recorder_runs_manager.recording_start
|
||||
)
|
||||
|
||||
|
||||
|
@ -64,10 +70,10 @@ async def test_run_history_while_recorder_is_not_yet_started(
|
|||
# Prevent the run history from starting to ensure
|
||||
# we can test run_history.current.start returns the expected value
|
||||
with patch(
|
||||
"homeassistant.components.recorder.run_history.RunHistory.start",
|
||||
"homeassistant.components.recorder.table_managers.recorder_runs.RecorderRunsManager.start",
|
||||
):
|
||||
instance = await async_setup_recorder_instance(hass)
|
||||
run_history = instance.run_history
|
||||
run_history = instance.recorder_runs_manager
|
||||
assert run_history.current.start == run_history.recording_start
|
||||
|
||||
def _start_run_history():
|
|
@ -1551,7 +1551,7 @@ async def test_database_corruption_while_running(
|
|||
await hass.async_block_till_done()
|
||||
caplog.clear()
|
||||
|
||||
original_start_time = get_instance(hass).run_history.recording_start
|
||||
original_start_time = get_instance(hass).recorder_runs_manager.recording_start
|
||||
|
||||
hass.states.async_set("test.lost", "on", {})
|
||||
|
||||
|
@ -1599,7 +1599,7 @@ async def test_database_corruption_while_running(
|
|||
assert state.entity_id == "test.two"
|
||||
assert state.state == "on"
|
||||
|
||||
new_start_time = get_instance(hass).run_history.recording_start
|
||||
new_start_time = get_instance(hass).recorder_runs_manager.recording_start
|
||||
assert original_start_time < new_start_time
|
||||
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
|
||||
|
|
|
@ -348,7 +348,7 @@ async def test_schema_migrate(
|
|||
|
||||
def _mock_setup_run(self):
|
||||
self.run_info = RecorderRuns(
|
||||
start=self.run_history.recording_start, created=dt_util.utcnow()
|
||||
start=self.recorder_runs_manager.recording_start, created=dt_util.utcnow()
|
||||
)
|
||||
|
||||
def _instrument_migrate_schema(*args):
|
||||
|
|
|
@ -27,8 +27,8 @@ async def test_recorder_system_health(
|
|||
info = await get_system_health_info(hass, "recorder")
|
||||
instance = get_instance(hass)
|
||||
assert info == {
|
||||
"current_recorder_run": instance.run_history.current.start,
|
||||
"oldest_recorder_run": instance.run_history.first.start,
|
||||
"current_recorder_run": instance.recorder_runs_manager.current.start,
|
||||
"oldest_recorder_run": instance.recorder_runs_manager.first.start,
|
||||
"estimated_db_size": ANY,
|
||||
"database_engine": SupportedDialect.SQLITE.value,
|
||||
"database_version": ANY,
|
||||
|
@ -53,8 +53,8 @@ async def test_recorder_system_health_alternate_dbms(
|
|||
info = await get_system_health_info(hass, "recorder")
|
||||
instance = get_instance(hass)
|
||||
assert info == {
|
||||
"current_recorder_run": instance.run_history.current.start,
|
||||
"oldest_recorder_run": instance.run_history.first.start,
|
||||
"current_recorder_run": instance.recorder_runs_manager.current.start,
|
||||
"oldest_recorder_run": instance.recorder_runs_manager.first.start,
|
||||
"estimated_db_size": "1.00 MiB",
|
||||
"database_engine": dialect_name.value,
|
||||
"database_version": ANY,
|
||||
|
@ -84,8 +84,8 @@ async def test_recorder_system_health_db_url_missing_host(
|
|||
):
|
||||
info = await get_system_health_info(hass, "recorder")
|
||||
assert info == {
|
||||
"current_recorder_run": instance.run_history.current.start,
|
||||
"oldest_recorder_run": instance.run_history.first.start,
|
||||
"current_recorder_run": instance.recorder_runs_manager.current.start,
|
||||
"oldest_recorder_run": instance.recorder_runs_manager.first.start,
|
||||
"estimated_db_size": "1.00 MiB",
|
||||
"database_engine": dialect_name.value,
|
||||
"database_version": ANY,
|
||||
|
@ -102,14 +102,16 @@ async def test_recorder_system_health_crashed_recorder_runs_table(
|
|||
# This test is specific for SQLite
|
||||
return
|
||||
|
||||
with patch("homeassistant.components.recorder.run_history.RunHistory.load_from_db"):
|
||||
with patch(
|
||||
"homeassistant.components.recorder.table_managers.recorder_runs.RecorderRunsManager.load_from_db"
|
||||
):
|
||||
assert await async_setup_component(hass, "system_health", {})
|
||||
instance = await async_setup_recorder_instance(hass)
|
||||
await async_wait_recording_done(hass)
|
||||
info = await get_system_health_info(hass, "recorder")
|
||||
assert info == {
|
||||
"current_recorder_run": instance.run_history.current.start,
|
||||
"oldest_recorder_run": instance.run_history.current.start,
|
||||
"current_recorder_run": instance.recorder_runs_manager.current.start,
|
||||
"oldest_recorder_run": instance.recorder_runs_manager.current.start,
|
||||
"estimated_db_size": ANY,
|
||||
"database_engine": SupportedDialect.SQLITE.value,
|
||||
"database_version": ANY,
|
||||
|
|
Loading…
Reference in New Issue