mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 09:47:13 +00:00
Fix recorder ws_info blocking the event loop (#110657)
* Fix recorder ws_info blocking the event loop Fixes ``` 2024-02-15 06:37:55.423 WARNING (MainThread) [asyncio] Executing <Task pending name=websocket_api.async:ws_info coro=<_handle_async_response() running at /usr/src/homeassistant/homeassistant/components/websocket_api/decorators.py:26> wait_for=<_GatheringFuture pending cb=[Task.task_wakeup()] created at /usr/local/lib/python3.12/asyncio/tasks.py:712> cb=[set.remove()] created at /usr/src/homeassistant/homeassistant/core.py:653> took 0.332 seconds ``` * no instance did not actually work
This commit is contained in:
parent
95015fbb40
commit
f9dc92a9a0
@ -187,6 +187,7 @@ class Recorder(threading.Thread):
|
|||||||
self.auto_purge = auto_purge
|
self.auto_purge = auto_purge
|
||||||
self.auto_repack = auto_repack
|
self.auto_repack = auto_repack
|
||||||
self.keep_days = keep_days
|
self.keep_days = keep_days
|
||||||
|
self.is_running: bool = False
|
||||||
self._hass_started: asyncio.Future[object] = hass.loop.create_future()
|
self._hass_started: asyncio.Future[object] = hass.loop.create_future()
|
||||||
self.commit_interval = commit_interval
|
self.commit_interval = commit_interval
|
||||||
self._queue: queue.SimpleQueue[RecorderTask | Event] = queue.SimpleQueue()
|
self._queue: queue.SimpleQueue[RecorderTask | Event] = queue.SimpleQueue()
|
||||||
@ -694,6 +695,7 @@ class Recorder(threading.Thread):
|
|||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
"""Run the recorder thread."""
|
"""Run the recorder thread."""
|
||||||
|
self.is_running = True
|
||||||
try:
|
try:
|
||||||
self._run()
|
self._run()
|
||||||
except Exception: # pylint: disable=broad-exception-caught
|
except Exception: # pylint: disable=broad-exception-caught
|
||||||
@ -703,6 +705,7 @@ class Recorder(threading.Thread):
|
|||||||
finally:
|
finally:
|
||||||
# Ensure shutdown happens cleanly if
|
# Ensure shutdown happens cleanly if
|
||||||
# anything goes wrong in the run loop
|
# anything goes wrong in the run loop
|
||||||
|
self.is_running = False
|
||||||
self._shutdown()
|
self._shutdown()
|
||||||
|
|
||||||
def _add_to_session(self, session: Session, obj: object) -> None:
|
def _add_to_session(self, session: Session, obj: object) -> None:
|
||||||
|
@ -44,13 +44,7 @@ from .statistics import (
|
|||||||
statistics_during_period,
|
statistics_during_period,
|
||||||
validate_statistics,
|
validate_statistics,
|
||||||
)
|
)
|
||||||
from .util import (
|
from .util import PERIOD_SCHEMA, get_instance, resolve_period
|
||||||
PERIOD_SCHEMA,
|
|
||||||
async_migration_in_progress,
|
|
||||||
async_migration_is_live,
|
|
||||||
get_instance,
|
|
||||||
resolve_period,
|
|
||||||
)
|
|
||||||
|
|
||||||
_LOGGER: logging.Logger = logging.getLogger(__package__)
|
_LOGGER: logging.Logger = logging.getLogger(__package__)
|
||||||
|
|
||||||
@ -497,21 +491,30 @@ def ws_info(
|
|||||||
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any]
|
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any]
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Return status of the recorder."""
|
"""Return status of the recorder."""
|
||||||
instance = get_instance(hass)
|
if instance := get_instance(hass):
|
||||||
|
backlog = instance.backlog
|
||||||
backlog = instance.backlog if instance else None
|
migration_in_progress = instance.migration_in_progress
|
||||||
migration_in_progress = async_migration_in_progress(hass)
|
migration_is_live = instance.migration_is_live
|
||||||
migration_is_live = async_migration_is_live(hass)
|
recording = instance.recording
|
||||||
recording = instance.recording if instance else False
|
# We avoid calling is_alive() as it can block waiting
|
||||||
thread_alive = instance.is_alive() if instance else False
|
# for the thread state lock which will block the event loop.
|
||||||
|
is_running = instance.is_running
|
||||||
|
max_backlog = instance.max_backlog
|
||||||
|
else:
|
||||||
|
backlog = None
|
||||||
|
migration_in_progress = False
|
||||||
|
migration_is_live = False
|
||||||
|
recording = False
|
||||||
|
is_running = False
|
||||||
|
max_backlog = None
|
||||||
|
|
||||||
recorder_info = {
|
recorder_info = {
|
||||||
"backlog": backlog,
|
"backlog": backlog,
|
||||||
"max_backlog": instance.max_backlog,
|
"max_backlog": max_backlog,
|
||||||
"migration_in_progress": migration_in_progress,
|
"migration_in_progress": migration_in_progress,
|
||||||
"migration_is_live": migration_is_live,
|
"migration_is_live": migration_is_live,
|
||||||
"recording": recording,
|
"recording": recording,
|
||||||
"thread_running": thread_alive,
|
"thread_running": is_running,
|
||||||
}
|
}
|
||||||
connection.send_result(msg["id"], recorder_info)
|
connection.send_result(msg["id"], recorder_info)
|
||||||
|
|
||||||
|
@ -2132,6 +2132,23 @@ async def test_recorder_info_bad_recorder_config(
|
|||||||
assert response["result"]["thread_running"] is False
|
assert response["result"]["thread_running"] is False
|
||||||
|
|
||||||
|
|
||||||
|
async def test_recorder_info_no_instance(
|
||||||
|
recorder_mock: Recorder, hass: HomeAssistant, hass_ws_client: WebSocketGenerator
|
||||||
|
) -> None:
|
||||||
|
"""Test getting recorder when there is no instance."""
|
||||||
|
client = await hass_ws_client()
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.recorder.websocket_api.get_instance",
|
||||||
|
return_value=None,
|
||||||
|
):
|
||||||
|
await client.send_json_auto_id({"type": "recorder/info"})
|
||||||
|
response = await client.receive_json()
|
||||||
|
assert response["success"]
|
||||||
|
assert response["result"]["recording"] is False
|
||||||
|
assert response["result"]["thread_running"] is False
|
||||||
|
|
||||||
|
|
||||||
async def test_recorder_info_migration_queue_exhausted(
|
async def test_recorder_info_migration_queue_exhausted(
|
||||||
hass: HomeAssistant, hass_ws_client: WebSocketGenerator
|
hass: HomeAssistant, hass_ws_client: WebSocketGenerator
|
||||||
) -> None:
|
) -> None:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user