Skip homekit_controller polls when system is overloaded and still trying to process the previous one (#25968)
* Skip async_update if there are signs of backpressure * Black * Only warn once * Log on recovery * Formatting fix
This commit is contained in:
parent
8da1879599
commit
2bd832cd7a
1 changed files with 34 additions and 15 deletions
|
@ -103,6 +103,10 @@ class HKDevice:
|
|||
# this method.
|
||||
self._polling_interval_remover = None
|
||||
|
||||
# Never allow concurrent polling of the same accessory or bridge
|
||||
self._polling_lock = asyncio.Lock()
|
||||
self._polling_lock_warned = False
|
||||
|
||||
def add_pollable_characteristics(self, characteristics):
|
||||
"""Add (aid, iid) pairs that we need to poll."""
|
||||
self.pollable_characteristics.extend(characteristics)
|
||||
|
@ -247,25 +251,40 @@ class HKDevice:
|
|||
_LOGGER.debug("HomeKit connection not polling any characteristics.")
|
||||
return
|
||||
|
||||
_LOGGER.debug("Starting HomeKit controller update")
|
||||
if self._polling_lock.locked():
|
||||
if not self._polling_lock_warned:
|
||||
_LOGGER.warning(
|
||||
"HomeKit controller update skipped as previous poll still in flight"
|
||||
)
|
||||
self._polling_lock_warned = True
|
||||
return
|
||||
|
||||
try:
|
||||
new_values_dict = await self.get_characteristics(
|
||||
self.pollable_characteristics
|
||||
if self._polling_lock_warned:
|
||||
_LOGGER.info(
|
||||
"HomeKit controller no longer detecting back pressure - not skipping poll"
|
||||
)
|
||||
except AccessoryNotFoundError:
|
||||
# Not only did the connection fail, but also the accessory is not
|
||||
# visible on the network.
|
||||
self.async_set_unavailable()
|
||||
return
|
||||
except (AccessoryDisconnectedError, EncryptionError):
|
||||
# Temporary connection failure. Device is still available but our
|
||||
# connection was dropped.
|
||||
return
|
||||
self._polling_lock_warned = False
|
||||
|
||||
self.process_new_events(new_values_dict)
|
||||
async with self._polling_lock:
|
||||
_LOGGER.debug("Starting HomeKit controller update")
|
||||
|
||||
_LOGGER.debug("Finished HomeKit controller update")
|
||||
try:
|
||||
new_values_dict = await self.get_characteristics(
|
||||
self.pollable_characteristics
|
||||
)
|
||||
except AccessoryNotFoundError:
|
||||
# Not only did the connection fail, but also the accessory is not
|
||||
# visible on the network.
|
||||
self.async_set_unavailable()
|
||||
return
|
||||
except (AccessoryDisconnectedError, EncryptionError):
|
||||
# Temporary connection failure. Device is still available but our
|
||||
# connection was dropped.
|
||||
return
|
||||
|
||||
self.process_new_events(new_values_dict)
|
||||
|
||||
_LOGGER.debug("Finished HomeKit controller update")
|
||||
|
||||
def process_new_events(self, new_values_dict):
|
||||
"""Process events from accessory into HA state."""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue