Ensure recorder shuts down when its startup future is canceled out from under it (#72866)

This commit is contained in:
J. Nick Koston 2022-06-01 19:13:09 -10:00 committed by GitHub
parent d368b9e24f
commit f79e5e002b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 3 deletions

View file

@ -3,6 +3,7 @@ from __future__ import annotations
import asyncio
from collections.abc import Callable, Iterable
from concurrent.futures import CancelledError
import contextlib
from datetime import datetime, timedelta
import logging
@ -518,9 +519,16 @@ class Recorder(threading.Thread):
def _wait_startup_or_shutdown(self) -> object | None:
"""Wait for startup or shutdown before starting."""
return asyncio.run_coroutine_threadsafe(
self._async_wait_for_started(), self.hass.loop
).result()
try:
return asyncio.run_coroutine_threadsafe(
self._async_wait_for_started(), self.hass.loop
).result()
except CancelledError as ex:
_LOGGER.warning(
"Recorder startup was externally canceled before it could complete: %s",
ex,
)
return SHUTDOWN_TASK
def run(self) -> None:
"""Start processing events to save."""

View file

@ -118,6 +118,26 @@ async def test_shutdown_before_startup_finishes(
assert run_info.end is not None
async def test_canceled_before_startup_finishes(
hass: HomeAssistant,
async_setup_recorder_instance: SetupRecorderInstanceT,
caplog: pytest.LogCaptureFixture,
):
"""Test recorder shuts down when its startup future is canceled out from under it."""
hass.state = CoreState.not_running
await async_setup_recorder_instance(hass)
instance = get_instance(hass)
await instance.async_db_ready
instance._hass_started.cancel()
with patch.object(instance, "engine"):
await hass.async_block_till_done()
await hass.async_add_executor_job(instance.join)
assert (
"Recorder startup was externally canceled before it could complete"
in caplog.text
)
async def test_shutdown_closes_connections(hass, recorder_mock):
"""Test shutdown closes connections."""