Warn if start takes a long time. (#6975)

* Warn if start takes a long time.

* ps - cleanup

* Tweak message

* Add tests

* Tweak messagE
This commit is contained in:
Paulus Schoutsen 2017-04-08 14:53:32 -07:00 committed by GitHub
parent 2277778d8d
commit 5d3fe83e62
2 changed files with 58 additions and 1 deletions

View File

@ -18,6 +18,7 @@ from time import monotonic
from types import MappingProxyType from types import MappingProxyType
from typing import Optional, Any, Callable, List # NOQA from typing import Optional, Any, Callable, List # NOQA
from async_timeout import timeout
import voluptuous as vol import voluptuous as vol
from voluptuous.humanize import humanize_error from voluptuous.humanize import humanize_error
@ -49,6 +50,8 @@ ENTITY_ID_PATTERN = re.compile(r"^(\w+)\.(\w+)$")
# Size of a executor pool # Size of a executor pool
EXECUTOR_POOL_SIZE = 10 EXECUTOR_POOL_SIZE = 10
# How long to wait till things that run on startup have to finish.
TIMEOUT_EVENT_START = 15
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -159,7 +162,18 @@ class HomeAssistant(object):
# pylint: disable=protected-access # pylint: disable=protected-access
self.loop._thread_ident = threading.get_ident() self.loop._thread_ident = threading.get_ident()
self.bus.async_fire(EVENT_HOMEASSISTANT_START) self.bus.async_fire(EVENT_HOMEASSISTANT_START)
yield from self.async_stop_track_tasks()
try:
with timeout(TIMEOUT_EVENT_START, loop=self.loop):
yield from self.async_stop_track_tasks()
except asyncio.TimeoutError:
_LOGGER.warning(
'Something is blocking Home Assistant from wrapping up the '
'start up phase. We\'re going to continue anyway. Please '
'report the following info at http://bit.ly/2ogP58T : %s',
', '.join(self.config.components))
self._track_task = False
self.state = CoreState.running self.state = CoreState.running
_async_create_timer(self) _async_create_timer(self)

View File

@ -5,6 +5,7 @@ import unittest
from unittest.mock import patch, MagicMock, sentinel from unittest.mock import patch, MagicMock, sentinel
from datetime import datetime, timedelta from datetime import datetime, timedelta
import logging
import pytz import pytz
import pytest import pytest
@ -867,3 +868,45 @@ def test_timer_out_of_sync(mock_monotonic, loop):
assert slp_seconds == 1 assert slp_seconds == 1
assert callback is fire_time_event assert callback is fire_time_event
assert abs(nxt - 12.3) < 0.001 assert abs(nxt - 12.3) < 0.001
@asyncio.coroutine
def test_hass_start_starts_the_timer(loop):
"""Test when hass starts, it starts the timer."""
hass = ha.HomeAssistant(loop=loop)
try:
with patch('homeassistant.core._async_create_timer') as mock_timer:
yield from hass.async_start()
assert hass.state == ha.CoreState.running
assert not hass._track_task
assert len(mock_timer.mock_calls) == 1
assert mock_timer.mock_calls[0][1][0] is hass
finally:
yield from hass.async_stop()
assert hass.state == ha.CoreState.not_running
@asyncio.coroutine
def test_start_taking_too_long(loop, caplog):
"""Test when async_start takes too long."""
hass = ha.HomeAssistant(loop=loop)
caplog.set_level(logging.WARNING)
try:
with patch('homeassistant.core.timeout',
side_effect=asyncio.TimeoutError), \
patch('homeassistant.core._async_create_timer') as mock_timer:
yield from hass.async_start()
assert not hass._track_task
assert hass.state == ha.CoreState.running
assert len(mock_timer.mock_calls) == 1
assert mock_timer.mock_calls[0][1][0] is hass
assert 'Something is blocking Home Assistant' in caplog.text
finally:
yield from hass.async_stop()
assert hass.state == ha.CoreState.not_running