Make dispatcher setup lazy (#74374)

This commit is contained in:
J. Nick Koston 2022-07-04 07:58:35 -05:00 committed by GitHub
parent dd57d7d77f
commit 6c3baf03aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 23 deletions

View file

@ -41,26 +41,13 @@ def async_dispatcher_connect(
"""
if DATA_DISPATCHER not in hass.data:
hass.data[DATA_DISPATCHER] = {}
job = HassJob(
catch_log_exception(
target,
lambda *args: "Exception in {} when dispatching '{}': {}".format(
# Functions wrapped in partial do not have a __name__
getattr(target, "__name__", None) or str(target),
signal,
args,
),
)
)
hass.data[DATA_DISPATCHER].setdefault(signal, []).append(job)
hass.data[DATA_DISPATCHER].setdefault(signal, {})[target] = None
@callback
def async_remove_dispatcher() -> None:
"""Remove signal listener."""
try:
hass.data[DATA_DISPATCHER][signal].remove(job)
del hass.data[DATA_DISPATCHER][signal][target]
except (KeyError, ValueError):
# KeyError is key target listener did not exist
# ValueError if listener did not exist within signal
@ -75,6 +62,21 @@ def dispatcher_send(hass: HomeAssistant, signal: str, *args: Any) -> None:
hass.loop.call_soon_threadsafe(async_dispatcher_send, hass, signal, *args)
def _generate_job(signal: str, target: Callable[..., Any]) -> HassJob:
"""Generate a HassJob for a signal and target."""
return HassJob(
catch_log_exception(
target,
lambda *args: "Exception in {} when dispatching '{}': {}".format(
# Functions wrapped in partial do not have a __name__
getattr(target, "__name__", None) or str(target),
signal,
args,
),
)
)
@callback
@bind_hass
def async_dispatcher_send(hass: HomeAssistant, signal: str, *args: Any) -> None:
@ -82,7 +84,9 @@ def async_dispatcher_send(hass: HomeAssistant, signal: str, *args: Any) -> None:
This method must be run in the event loop.
"""
target_list = hass.data.get(DATA_DISPATCHER, {}).get(signal, [])
for job in target_list:
target_list = hass.data.get(DATA_DISPATCHER, {}).get(signal, {})
for target, job in target_list.items():
if job is None:
job = _generate_job(signal, target)
target_list[target] = job
hass.async_add_hass_job(job, *args)