From faceb4c1dc0ac52212ef6fe9c9263cddc2fd9fa8 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 6 Nov 2016 23:12:20 -0800 Subject: [PATCH] Sequential updates for non-async entities --- homeassistant/helpers/entity_component.py | 36 ++++++++++++++++++----- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/homeassistant/helpers/entity_component.py b/homeassistant/helpers/entity_component.py index a648de1d650..f4ca2f1274f 100644 --- a/homeassistant/helpers/entity_component.py +++ b/homeassistant/helpers/entity_component.py @@ -279,6 +279,7 @@ class EntityPlatform(object): self.entity_namespace = entity_namespace self.platform_entities = [] self._async_unsub_polling = None + self._process_updates = False def add_entities(self, new_entities, update_before_add=False): """Add entities for a single platform.""" @@ -335,14 +336,35 @@ class EntityPlatform(object): self._async_unsub_polling() self._async_unsub_polling = None - @callback + @asyncio.coroutine def _update_entity_states(self, now): """Update the states of all the polling entities. - + To protect from flooding the executor, we will update async entities + in parallel and other entities sequential. This method must be run in the event loop. """ - for entity in self.platform_entities: - if entity.should_poll: - self.component.hass.loop.create_task( - entity.async_update_ha_state(True) - ) + if self._process_updates: + return + self._process_updates = True + + try: + tasks = [] + to_update = [] + + for entity in self.platform_entities: + if not entity.should_poll: + continue + + update_coro = entity.async_update_ha_state(True) + if hasattr(entity, 'async_update'): + tasks.append(update_coro) + else: + to_update.append(update_coro) + + for update_coro in to_update: + yield from update_coro + + if tasks: + yield from asyncio.wait(tasks, loop=self.component.hass.loop) + finally: + self._process_updates = False