Small speed up to async_track_event (#116083)

This commit is contained in:
J. Nick Koston 2024-04-24 09:56:59 +02:00 committed by GitHub
parent ec377ce665
commit b520efb87a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 14 additions and 22 deletions

View File

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