mirror of
https://github.com/home-assistant/core.git
synced 2025-12-24 04:50:05 +00:00
Prevent entities running multiple updates simultaneously (#6511)
* Protect entity for multible updates on same time. * Address all comments / make update more robust * fix unittest * fix lint * address comments
This commit is contained in:
committed by
Paulus Schoutsen
parent
c4e151f621
commit
5529d77c62
@@ -19,6 +19,7 @@ from homeassistant.util.async import (
|
||||
run_coroutine_threadsafe, run_callback_threadsafe)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
SLOW_UPDATE_WARNING = 10
|
||||
|
||||
|
||||
def generate_entity_id(entity_id_format: str, name: Optional[str],
|
||||
@@ -70,6 +71,9 @@ class Entity(object):
|
||||
# If we reported if this entity was slow
|
||||
_slow_reported = False
|
||||
|
||||
# protect for multible updates
|
||||
_update_warn = None
|
||||
|
||||
@property
|
||||
def should_poll(self) -> bool:
|
||||
"""Return True if entity has to be polled for state.
|
||||
@@ -199,12 +203,32 @@ class Entity(object):
|
||||
raise NoEntitySpecifiedError(
|
||||
"No entity id specified for entity {}".format(self.name))
|
||||
|
||||
# update entity data
|
||||
if force_refresh:
|
||||
if hasattr(self, 'async_update'):
|
||||
# pylint: disable=no-member
|
||||
yield from self.async_update()
|
||||
else:
|
||||
yield from self.hass.loop.run_in_executor(None, self.update)
|
||||
if self._update_warn:
|
||||
_LOGGER.warning('Update for %s is already in progress',
|
||||
self.entity_id)
|
||||
return
|
||||
|
||||
self._update_warn = self.hass.loop.call_later(
|
||||
SLOW_UPDATE_WARNING, _LOGGER.warning,
|
||||
'Update of %s is taking over %s seconds.', self.entity_id,
|
||||
SLOW_UPDATE_WARNING
|
||||
)
|
||||
|
||||
try:
|
||||
if hasattr(self, 'async_update'):
|
||||
# pylint: disable=no-member
|
||||
yield from self.async_update()
|
||||
else:
|
||||
yield from self.hass.loop.run_in_executor(
|
||||
None, self.update)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception('Update for %s fails', self.entity_id)
|
||||
return
|
||||
finally:
|
||||
self._update_warn.cancel()
|
||||
self._update_warn = None
|
||||
|
||||
start = timer()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user