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

* Warn if start takes a long time.

* ps - cleanup

* Tweak message

* Add tests

* Tweak messagE
pull/6956/head
Paulus Schoutsen 2017-04-08 14:53:32 -07:00
parent 5a2ab3167b
commit dea9aec268
2 changed files with 58 additions and 1 deletions

View File

@ -18,6 +18,7 @@ from time import monotonic
from types import MappingProxyType
from typing import Optional, Any, Callable, List # NOQA
from async_timeout import timeout
import voluptuous as vol
from voluptuous.humanize import humanize_error
@ -49,6 +50,8 @@ ENTITY_ID_PATTERN = re.compile(r"^(\w+)\.(\w+)$")
# Size of a executor pool
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__)
@ -159,7 +162,18 @@ class HomeAssistant(object):
# pylint: disable=protected-access
self.loop._thread_ident = threading.get_ident()
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
_async_create_timer(self)

View File

@ -5,6 +5,7 @@ import unittest
from unittest.mock import patch, MagicMock, sentinel
from datetime import datetime, timedelta
import logging
import pytz
import pytest
@ -867,3 +868,45 @@ def test_timer_out_of_sync(mock_monotonic, loop):
assert slp_seconds == 1
assert callback is fire_time_event
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