mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 09:17:10 +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_repack = auto_repack
|
||||
self.keep_days = keep_days
|
||||
self.is_running: bool = False
|
||||
self._hass_started: asyncio.Future[object] = hass.loop.create_future()
|
||||
self.commit_interval = commit_interval
|
||||
self._queue: queue.SimpleQueue[RecorderTask | Event] = queue.SimpleQueue()
|
||||
@ -694,6 +695,7 @@ class Recorder(threading.Thread):
|
||||
|
||||
def run(self) -> None:
|
||||
"""Run the recorder thread."""
|
||||
self.is_running = True
|
||||
try:
|
||||
self._run()
|
||||
except Exception: # pylint: disable=broad-exception-caught
|
||||
@ -703,6 +705,7 @@ class Recorder(threading.Thread):
|
||||
finally:
|
||||
# Ensure shutdown happens cleanly if
|
||||
# anything goes wrong in the run loop
|
||||
self.is_running = False
|
||||
self._shutdown()
|
||||
|
||||
def _add_to_session(self, session: Session, obj: object) -> None:
|
||||
|
@ -44,13 +44,7 @@ from .statistics import (
|
||||
statistics_during_period,
|
||||
validate_statistics,
|
||||
)
|
||||
from .util import (
|
||||
PERIOD_SCHEMA,
|
||||
async_migration_in_progress,
|
||||
async_migration_is_live,
|
||||
get_instance,
|
||||
resolve_period,
|
||||
)
|
||||
from .util import PERIOD_SCHEMA, get_instance, resolve_period
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__package__)
|
||||
|
||||
@ -497,21 +491,30 @@ def ws_info(
|
||||
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any]
|
||||
) -> None:
|
||||
"""Return status of the recorder."""
|
||||
instance = get_instance(hass)
|
||||
|
||||
backlog = instance.backlog if instance else None
|
||||
migration_in_progress = async_migration_in_progress(hass)
|
||||
migration_is_live = async_migration_is_live(hass)
|
||||
recording = instance.recording if instance else False
|
||||
thread_alive = instance.is_alive() if instance else False
|
||||
if instance := get_instance(hass):
|
||||
backlog = instance.backlog
|
||||
migration_in_progress = instance.migration_in_progress
|
||||
migration_is_live = instance.migration_is_live
|
||||
recording = instance.recording
|
||||
# We avoid calling is_alive() as it can block waiting
|
||||
# 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 = {
|
||||
"backlog": backlog,
|
||||
"max_backlog": instance.max_backlog,
|
||||
"max_backlog": max_backlog,
|
||||
"migration_in_progress": migration_in_progress,
|
||||
"migration_is_live": migration_is_live,
|
||||
"recording": recording,
|
||||
"thread_running": thread_alive,
|
||||
"thread_running": is_running,
|
||||
}
|
||||
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
|
||||
|
||||
|
||||
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(
|
||||
hass: HomeAssistant, hass_ws_client: WebSocketGenerator
|
||||
) -> None:
|
||||
|
Loading…
x
Reference in New Issue
Block a user