Determine how to run listeners at setup time instead of execution time (#41304)

This commit is contained in:
J. Nick Koston 2020-10-07 09:51:50 -05:00 committed by GitHub
parent 8d94dff75c
commit 9e1461da62
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 216 additions and 119 deletions

View file

@ -2,7 +2,7 @@
import logging
from typing import Any, Callable
from homeassistant.core import callback
from homeassistant.core import HassJob, callback
from homeassistant.loader import bind_hass
from homeassistant.util.async_ import run_callback_threadsafe
from homeassistant.util.logging import catch_log_exception
@ -41,26 +41,25 @@ def async_dispatcher_connect(
if DATA_DISPATCHER not in hass.data:
hass.data[DATA_DISPATCHER] = {}
if signal not in hass.data[DATA_DISPATCHER]:
hass.data[DATA_DISPATCHER][signal] = []
wrapped_target = 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,
),
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][signal].append(wrapped_target)
hass.data[DATA_DISPATCHER].setdefault(signal, []).append(job)
@callback
def async_remove_dispatcher() -> None:
"""Remove signal listener."""
try:
hass.data[DATA_DISPATCHER][signal].remove(wrapped_target)
hass.data[DATA_DISPATCHER][signal].remove(job)
except (KeyError, ValueError):
# KeyError is key target listener did not exist
# ValueError if listener did not exist within signal
@ -84,5 +83,5 @@ def async_dispatcher_send(hass: HomeAssistantType, signal: str, *args: Any) -> N
"""
target_list = hass.data.get(DATA_DISPATCHER, {}).get(signal, [])
for target in target_list:
hass.async_add_job(target, *args)
for job in target_list:
hass.async_add_hass_job(job, *args)