Fix mobile app dispatcher performance (#99647)

Fix mobile app thundering heard

The mobile_app would setup a dispatcher to listener for updates on
every entity and reject the ones that were not for the unique id
that it was intrested in.

Instead we now register for a signal per unique id since we were
previously generating O(entities*sensors*devices) callbacks which
was causing the event loop to stall when there were a large
number of mobile app users.
This commit is contained in:
J. Nick Koston 2023-09-04 19:56:34 -05:00 committed by GitHub
parent ff2e0c570b
commit fed1cab847
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 9 additions and 9 deletions

View file

@ -1,6 +1,8 @@
"""A entity class for mobile_app."""
from __future__ import annotations
from typing import Any
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_ICON, CONF_NAME, CONF_UNIQUE_ID, STATE_UNAVAILABLE
from homeassistant.core import callback
@ -36,7 +38,9 @@ class MobileAppEntity(RestoreEntity):
"""Register callbacks."""
self.async_on_remove(
async_dispatcher_connect(
self.hass, SIGNAL_SENSOR_UPDATE, self._handle_update
self.hass,
f"{SIGNAL_SENSOR_UPDATE}-{self._attr_unique_id}",
self._handle_update,
)
)
@ -96,10 +100,7 @@ class MobileAppEntity(RestoreEntity):
return self._config.get(ATTR_SENSOR_STATE) != STATE_UNAVAILABLE
@callback
def _handle_update(self, incoming_id, data):
def _handle_update(self, data: dict[str, Any]) -> None:
"""Handle async event updates."""
if incoming_id != self._attr_unique_id:
return
self._config = {**self._config, **data}
self._config.update(data)
self.async_write_ha_state()

View file

@ -607,7 +607,7 @@ async def webhook_register_sensor(
if changes:
entity_registry.async_update_entity(existing_sensor, **changes)
async_dispatcher_send(hass, SIGNAL_SENSOR_UPDATE, unique_store_key, data)
async_dispatcher_send(hass, f"{SIGNAL_SENSOR_UPDATE}-{unique_store_key}", data)
else:
data[CONF_UNIQUE_ID] = unique_store_key
data[
@ -693,8 +693,7 @@ async def webhook_update_sensor_states(
sensor[CONF_WEBHOOK_ID] = config_entry.data[CONF_WEBHOOK_ID]
async_dispatcher_send(
hass,
SIGNAL_SENSOR_UPDATE,
unique_store_key,
f"{SIGNAL_SENSOR_UPDATE}-{unique_store_key}",
sensor,
)