Speed up singleton decorator so it can be used more places (#116292)
This commit is contained in:
parent
48b1678075
commit
ab2ea6100c
6 changed files with 25 additions and 28 deletions
|
@ -90,7 +90,11 @@ from .helpers.system_info import async_get_system_info
|
|||
from .helpers.typing import ConfigType
|
||||
from .setup import (
|
||||
BASE_PLATFORMS,
|
||||
DATA_SETUP_STARTED,
|
||||
# _setup_started is marked as protected to make it clear
|
||||
# that it is not part of the public API and should not be used
|
||||
# by integrations. It is only used for internal tracking of
|
||||
# which integrations are being set up.
|
||||
_setup_started,
|
||||
async_get_setup_timings,
|
||||
async_notify_setup_error,
|
||||
async_set_domains_to_be_loaded,
|
||||
|
@ -913,9 +917,7 @@ async def _async_set_up_integrations(
|
|||
hass: core.HomeAssistant, config: dict[str, Any]
|
||||
) -> None:
|
||||
"""Set up all the integrations."""
|
||||
setup_started: dict[tuple[str, str | None], float] = {}
|
||||
hass.data[DATA_SETUP_STARTED] = setup_started
|
||||
watcher = _WatchPendingSetups(hass, setup_started)
|
||||
watcher = _WatchPendingSetups(hass, _setup_started(hass))
|
||||
watcher.async_start()
|
||||
|
||||
domains_to_setup, integration_cache = await _async_resolve_domains_to_setup(
|
||||
|
|
|
@ -66,7 +66,7 @@ from homeassistant.loader import async_suggest_report_issue, bind_hass
|
|||
from homeassistant.util import ensure_unique_string, slugify
|
||||
from homeassistant.util.frozen_dataclass_compat import FrozenOrThawed
|
||||
|
||||
from . import device_registry as dr, entity_registry as er
|
||||
from . import device_registry as dr, entity_registry as er, singleton
|
||||
from .device_registry import DeviceInfo, EventDeviceRegistryUpdatedData
|
||||
from .event import (
|
||||
async_track_device_registry_updated_event,
|
||||
|
@ -98,15 +98,15 @@ CONTEXT_RECENT_TIME_SECONDS = 5 # Time that a context is considered recent
|
|||
@callback
|
||||
def async_setup(hass: HomeAssistant) -> None:
|
||||
"""Set up entity sources."""
|
||||
hass.data[DATA_ENTITY_SOURCE] = {}
|
||||
entity_sources(hass)
|
||||
|
||||
|
||||
@callback
|
||||
@bind_hass
|
||||
@singleton.singleton(DATA_ENTITY_SOURCE)
|
||||
def entity_sources(hass: HomeAssistant) -> dict[str, EntityInfo]:
|
||||
"""Get the entity sources."""
|
||||
_entity_sources: dict[str, EntityInfo] = hass.data[DATA_ENTITY_SOURCE]
|
||||
return _entity_sources
|
||||
return {}
|
||||
|
||||
|
||||
def generate_entity_id(
|
||||
|
@ -1486,7 +1486,7 @@ class Entity(
|
|||
# The check for self.platform guards against integrations not using an
|
||||
# EntityComponent and can be removed in HA Core 2024.1
|
||||
if self.platform:
|
||||
self.hass.data[DATA_ENTITY_SOURCE].pop(self.entity_id)
|
||||
entity_sources(self.hass).pop(self.entity_id)
|
||||
|
||||
@callback
|
||||
def _async_registry_updated(
|
||||
|
|
|
@ -25,6 +25,7 @@ def singleton(data_key: str) -> Callable[[_FuncType[_T]], _FuncType[_T]]:
|
|||
"""Wrap a function with caching logic."""
|
||||
if not asyncio.iscoroutinefunction(func):
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
@bind_hass
|
||||
@functools.wraps(func)
|
||||
def wrapped(hass: HomeAssistant) -> _T:
|
||||
|
|
|
@ -24,6 +24,8 @@ from homeassistant.loader import (
|
|||
)
|
||||
from homeassistant.util.json import load_json
|
||||
|
||||
from . import singleton
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
TRANSLATION_FLATTEN_CACHE = "translation_flatten_cache"
|
||||
|
@ -370,11 +372,10 @@ def async_get_cached_translations(
|
|||
)
|
||||
|
||||
|
||||
@callback
|
||||
@singleton.singleton(TRANSLATION_FLATTEN_CACHE)
|
||||
def _async_get_translations_cache(hass: HomeAssistant) -> _TranslationCache:
|
||||
"""Return the translation cache."""
|
||||
cache: _TranslationCache = hass.data[TRANSLATION_FLATTEN_CACHE]
|
||||
return cache
|
||||
return _TranslationCache(hass)
|
||||
|
||||
|
||||
@callback
|
||||
|
@ -385,7 +386,7 @@ def async_setup(hass: HomeAssistant) -> None:
|
|||
"""
|
||||
cache = _TranslationCache(hass)
|
||||
current_language = hass.config.language
|
||||
hass.data[TRANSLATION_FLATTEN_CACHE] = cache
|
||||
_async_get_translations_cache(hass)
|
||||
|
||||
@callback
|
||||
def _async_load_translations_filter(event_data: Mapping[str, Any]) -> bool:
|
||||
|
|
|
@ -12,6 +12,7 @@ from packaging.requirements import Requirement
|
|||
|
||||
from .core import HomeAssistant, callback
|
||||
from .exceptions import HomeAssistantError
|
||||
from .helpers import singleton
|
||||
from .helpers.typing import UNDEFINED, UndefinedType
|
||||
from .loader import Integration, IntegrationNotFound, async_get_integration
|
||||
from .util import package as pkg_util
|
||||
|
@ -72,14 +73,10 @@ async def async_load_installed_versions(
|
|||
|
||||
|
||||
@callback
|
||||
@singleton.singleton(DATA_REQUIREMENTS_MANAGER)
|
||||
def _async_get_manager(hass: HomeAssistant) -> RequirementsManager:
|
||||
"""Get the requirements manager."""
|
||||
if DATA_REQUIREMENTS_MANAGER in hass.data:
|
||||
manager: RequirementsManager = hass.data[DATA_REQUIREMENTS_MANAGER]
|
||||
return manager
|
||||
|
||||
manager = hass.data[DATA_REQUIREMENTS_MANAGER] = RequirementsManager(hass)
|
||||
return manager
|
||||
return RequirementsManager(hass)
|
||||
|
||||
|
||||
@callback
|
||||
|
|
|
@ -29,7 +29,7 @@ from .core import (
|
|||
callback,
|
||||
)
|
||||
from .exceptions import DependencyError, HomeAssistantError
|
||||
from .helpers import translation
|
||||
from .helpers import singleton, translation
|
||||
from .helpers.issue_registry import IssueSeverity, async_create_issue
|
||||
from .helpers.typing import ConfigType
|
||||
from .util.async_ import create_eager_task
|
||||
|
@ -671,13 +671,12 @@ class SetupPhases(StrEnum):
|
|||
"""Wait time for the packages to import."""
|
||||
|
||||
|
||||
@singleton.singleton(DATA_SETUP_STARTED)
|
||||
def _setup_started(
|
||||
hass: core.HomeAssistant,
|
||||
) -> dict[tuple[str, str | None], float]:
|
||||
"""Return the setup started dict."""
|
||||
if DATA_SETUP_STARTED not in hass.data:
|
||||
hass.data[DATA_SETUP_STARTED] = {}
|
||||
return hass.data[DATA_SETUP_STARTED] # type: ignore[no-any-return]
|
||||
return {}
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
@ -717,15 +716,12 @@ def async_pause_setup(
|
|||
)
|
||||
|
||||
|
||||
@singleton.singleton(DATA_SETUP_TIME)
|
||||
def _setup_times(
|
||||
hass: core.HomeAssistant,
|
||||
) -> defaultdict[str, defaultdict[str | None, defaultdict[SetupPhases, float]]]:
|
||||
"""Return the setup timings default dict."""
|
||||
if DATA_SETUP_TIME not in hass.data:
|
||||
hass.data[DATA_SETUP_TIME] = defaultdict(
|
||||
lambda: defaultdict(lambda: defaultdict(float))
|
||||
)
|
||||
return hass.data[DATA_SETUP_TIME] # type: ignore[no-any-return]
|
||||
return defaultdict(lambda: defaultdict(lambda: defaultdict(float)))
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
|
Loading…
Add table
Reference in a new issue