mirror of https://github.com/home-assistant/core
Small speed up to async_track_event (#116083)
This commit is contained in:
parent
ec377ce665
commit
b520efb87a
|
@ -3,11 +3,12 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from collections import defaultdict
|
||||||
from collections.abc import Callable, Coroutine, Iterable, Mapping, Sequence
|
from collections.abc import Callable, Coroutine, Iterable, Mapping, Sequence
|
||||||
import copy
|
import copy
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import functools as ft
|
from functools import partial, wraps
|
||||||
import logging
|
import logging
|
||||||
from random import randint
|
from random import randint
|
||||||
import time
|
import time
|
||||||
|
@ -161,7 +162,7 @@ def threaded_listener_factory(
|
||||||
) -> Callable[Concatenate[HomeAssistant, _P], CALLBACK_TYPE]:
|
) -> Callable[Concatenate[HomeAssistant, _P], CALLBACK_TYPE]:
|
||||||
"""Convert an async event helper to a threaded one."""
|
"""Convert an async event helper to a threaded one."""
|
||||||
|
|
||||||
@ft.wraps(async_factory)
|
@wraps(async_factory)
|
||||||
def factory(
|
def factory(
|
||||||
hass: HomeAssistant, *args: _P.args, **kwargs: _P.kwargs
|
hass: HomeAssistant, *args: _P.args, **kwargs: _P.kwargs
|
||||||
) -> CALLBACK_TYPE:
|
) -> CALLBACK_TYPE:
|
||||||
|
@ -170,7 +171,7 @@ def threaded_listener_factory(
|
||||||
raise TypeError("First parameter needs to be a hass instance")
|
raise TypeError("First parameter needs to be a hass instance")
|
||||||
|
|
||||||
async_remove = run_callback_threadsafe(
|
async_remove = run_callback_threadsafe(
|
||||||
hass.loop, ft.partial(async_factory, hass, *args, **kwargs)
|
hass.loop, partial(async_factory, hass, *args, **kwargs)
|
||||||
).result()
|
).result()
|
||||||
|
|
||||||
def remove() -> None:
|
def remove() -> None:
|
||||||
|
@ -409,19 +410,16 @@ def _async_track_event(
|
||||||
return _remove_empty_listener
|
return _remove_empty_listener
|
||||||
|
|
||||||
hass_data = hass.data
|
hass_data = hass.data
|
||||||
callbacks_key = tracker.callbacks_key
|
callbacks: defaultdict[str, list[HassJob[[Event[_TypedDictT]], Any]]] | None
|
||||||
|
if not (callbacks := hass_data.get(tracker.callbacks_key)):
|
||||||
callbacks: dict[str, list[HassJob[[Event[_TypedDictT]], Any]]] | None
|
callbacks = hass_data[tracker.callbacks_key] = defaultdict(list)
|
||||||
if not (callbacks := hass_data.get(callbacks_key)):
|
|
||||||
callbacks = hass_data[callbacks_key] = {}
|
|
||||||
|
|
||||||
listeners_key = tracker.listeners_key
|
listeners_key = tracker.listeners_key
|
||||||
|
if tracker.listeners_key not in hass_data:
|
||||||
if listeners_key not in hass_data:
|
hass_data[tracker.listeners_key] = hass.bus.async_listen(
|
||||||
hass_data[listeners_key] = hass.bus.async_listen(
|
|
||||||
tracker.event_type,
|
tracker.event_type,
|
||||||
ft.partial(tracker.dispatcher_callable, hass, callbacks),
|
partial(tracker.dispatcher_callable, hass, callbacks),
|
||||||
event_filter=ft.partial(tracker.filter_callable, hass, callbacks),
|
event_filter=partial(tracker.filter_callable, hass, callbacks),
|
||||||
)
|
)
|
||||||
|
|
||||||
job = HassJob(action, f"track {tracker.event_type} event {keys}", job_type=job_type)
|
job = HassJob(action, f"track {tracker.event_type} event {keys}", job_type=job_type)
|
||||||
|
@ -432,19 +430,13 @@ def _async_track_event(
|
||||||
# here because this function gets called ~20000 times
|
# here because this function gets called ~20000 times
|
||||||
# during startup, and we want to avoid the overhead of
|
# during startup, and we want to avoid the overhead of
|
||||||
# creating empty lists and throwing them away.
|
# creating empty lists and throwing them away.
|
||||||
if callback_list := callbacks.get(keys):
|
callbacks[keys].append(job)
|
||||||
callback_list.append(job)
|
|
||||||
else:
|
|
||||||
callbacks[keys] = [job]
|
|
||||||
keys = [keys]
|
keys = [keys]
|
||||||
else:
|
else:
|
||||||
for key in keys:
|
for key in keys:
|
||||||
if callback_list := callbacks.get(key):
|
callbacks[key].append(job)
|
||||||
callback_list.append(job)
|
|
||||||
else:
|
|
||||||
callbacks[key] = [job]
|
|
||||||
|
|
||||||
return ft.partial(_remove_listener, hass, listeners_key, keys, job, callbacks)
|
return partial(_remove_listener, hass, listeners_key, keys, job, callbacks)
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
|
|
Loading…
Reference in New Issue