mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 00:37:53 +00:00
No wait for start and more async
This commit is contained in:
parent
7cd6f9038c
commit
5d007e636b
@ -7,6 +7,7 @@ to query this database.
|
||||
For more details about this component, please refer to the documentation at
|
||||
https://home-assistant.io/components/recorder/
|
||||
"""
|
||||
import asyncio
|
||||
import logging
|
||||
import queue
|
||||
import threading
|
||||
@ -20,7 +21,7 @@ import voluptuous as vol
|
||||
from homeassistant.core import HomeAssistant, callback, split_entity_id
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID, CONF_ENTITIES, CONF_EXCLUDE, CONF_DOMAINS,
|
||||
CONF_INCLUDE, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP,
|
||||
CONF_INCLUDE, EVENT_HOMEASSISTANT_STOP,
|
||||
EVENT_STATE_CHANGED, EVENT_TIME_CHANGED, MATCH_ALL)
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
@ -83,7 +84,18 @@ def session_scope():
|
||||
session.close()
|
||||
|
||||
|
||||
def get_instance() -> None:
|
||||
@asyncio.coroutine
|
||||
def async_get_instance():
|
||||
"""Throw error if recorder not initialized."""
|
||||
if _INSTANCE is None:
|
||||
raise RuntimeError("Recorder not initialized.")
|
||||
|
||||
yield from _INSTANCE.async_db_ready.wait()
|
||||
|
||||
return _INSTANCE
|
||||
|
||||
|
||||
def get_instance():
|
||||
"""Throw error if recorder not initialized."""
|
||||
if _INSTANCE is None:
|
||||
raise RuntimeError("Recorder not initialized.")
|
||||
@ -200,7 +212,7 @@ class Recorder(threading.Thread):
|
||||
self.recording_start = dt_util.utcnow()
|
||||
self.db_url = uri
|
||||
self.db_ready = threading.Event()
|
||||
self.start_recording = threading.Event()
|
||||
self.async_db_ready = asyncio.Event(loop=hass.loop)
|
||||
self.engine = None # type: Any
|
||||
self._run = None # type: Any
|
||||
|
||||
@ -209,11 +221,6 @@ class Recorder(threading.Thread):
|
||||
self.exclude = exclude.get(CONF_ENTITIES, []) + \
|
||||
exclude.get(CONF_DOMAINS, [])
|
||||
|
||||
def start_recording(event):
|
||||
"""Start recording."""
|
||||
self.start_recording.set()
|
||||
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_recording)
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, self.shutdown)
|
||||
hass.bus.listen(MATCH_ALL, self.event_listener)
|
||||
|
||||
@ -229,6 +236,7 @@ class Recorder(threading.Thread):
|
||||
self._setup_connection()
|
||||
self._setup_run()
|
||||
self.db_ready.set()
|
||||
self.async_db_ready.set()
|
||||
break
|
||||
except SQLAlchemyError as err:
|
||||
_LOGGER.error("Error during connection setup: %s (retrying "
|
||||
@ -239,8 +247,6 @@ class Recorder(threading.Thread):
|
||||
async_track_time_interval(
|
||||
self.hass, self._purge_old_data, timedelta(days=2))
|
||||
|
||||
_wait(self.start_recording, "Waiting to start recording", 90)
|
||||
|
||||
while True:
|
||||
event = self.queue.get()
|
||||
|
||||
@ -297,9 +303,6 @@ class Recorder(threading.Thread):
|
||||
"""Tell the recorder to shut down."""
|
||||
global _INSTANCE # pylint: disable=global-statement
|
||||
self.queue.put(None)
|
||||
if not self.start_recording.is_set():
|
||||
_LOGGER.warning("Recorder never started correctly")
|
||||
self.start_recording.set()
|
||||
self.join()
|
||||
_INSTANCE = None
|
||||
|
||||
@ -499,13 +502,13 @@ class Recorder(threading.Thread):
|
||||
return False
|
||||
|
||||
|
||||
def _wait(event, message, interval=15):
|
||||
def _wait(event, message):
|
||||
"""Event wait helper."""
|
||||
for mult in range(1, 4):
|
||||
event.wait(interval)
|
||||
for retry in (10, 20, 30):
|
||||
event.wait(10)
|
||||
if event.is_set():
|
||||
return
|
||||
msg = "{} ({} seconds)".format(message, interval*mult)
|
||||
msg = "{} ({} seconds)".format(message, retry)
|
||||
_LOGGER.warning(msg)
|
||||
if not event.is_set():
|
||||
raise HomeAssistantError(msg)
|
||||
|
@ -6,7 +6,8 @@ from datetime import timedelta
|
||||
from homeassistant.core import HomeAssistant, CoreState, callback
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_START
|
||||
from homeassistant.components.history import get_states, last_recorder_run
|
||||
from homeassistant.components.recorder import DOMAIN as _RECORDER
|
||||
from homeassistant.components.recorder import (
|
||||
async_get_instance, DOMAIN as _RECORDER)
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@ -57,6 +58,8 @@ def async_get_last_state(hass, entity_id: str):
|
||||
hass.state)
|
||||
return None
|
||||
|
||||
yield from async_get_instance() # Ensure recorder ready
|
||||
|
||||
if _LOCK not in hass.data:
|
||||
hass.data[_LOCK] = asyncio.Lock(loop=hass.loop)
|
||||
|
||||
|
@ -11,7 +11,8 @@ from homeassistant.components import input_boolean, recorder
|
||||
from homeassistant.helpers.restore_state import (
|
||||
async_get_last_state, DATA_RESTORE_CACHE)
|
||||
|
||||
from tests.common import get_test_home_assistant, init_recorder_component
|
||||
from tests.common import (
|
||||
get_test_home_assistant, mock_coro, init_recorder_component)
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
@ -29,7 +30,9 @@ def test_caching_data(hass):
|
||||
with patch('homeassistant.helpers.restore_state.last_recorder_run',
|
||||
return_value=MagicMock(end=dt_util.utcnow())), \
|
||||
patch('homeassistant.helpers.restore_state.get_states',
|
||||
return_value=states):
|
||||
return_value=states), \
|
||||
patch('homeassistant.helpers.restore_state.async_get_instance',
|
||||
return_value=mock_coro()):
|
||||
state = yield from async_get_last_state(hass, 'input_boolean.b1')
|
||||
|
||||
assert DATA_RESTORE_CACHE in hass.data
|
||||
|
Loading…
x
Reference in New Issue
Block a user