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 .helpers.typing import ConfigType
|
||||||
from .setup import (
|
from .setup import (
|
||||||
BASE_PLATFORMS,
|
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_get_setup_timings,
|
||||||
async_notify_setup_error,
|
async_notify_setup_error,
|
||||||
async_set_domains_to_be_loaded,
|
async_set_domains_to_be_loaded,
|
||||||
|
@ -913,9 +917,7 @@ async def _async_set_up_integrations(
|
||||||
hass: core.HomeAssistant, config: dict[str, Any]
|
hass: core.HomeAssistant, config: dict[str, Any]
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up all the integrations."""
|
"""Set up all the integrations."""
|
||||||
setup_started: dict[tuple[str, str | None], float] = {}
|
watcher = _WatchPendingSetups(hass, _setup_started(hass))
|
||||||
hass.data[DATA_SETUP_STARTED] = setup_started
|
|
||||||
watcher = _WatchPendingSetups(hass, setup_started)
|
|
||||||
watcher.async_start()
|
watcher.async_start()
|
||||||
|
|
||||||
domains_to_setup, integration_cache = await _async_resolve_domains_to_setup(
|
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 import ensure_unique_string, slugify
|
||||||
from homeassistant.util.frozen_dataclass_compat import FrozenOrThawed
|
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 .device_registry import DeviceInfo, EventDeviceRegistryUpdatedData
|
||||||
from .event import (
|
from .event import (
|
||||||
async_track_device_registry_updated_event,
|
async_track_device_registry_updated_event,
|
||||||
|
@ -98,15 +98,15 @@ CONTEXT_RECENT_TIME_SECONDS = 5 # Time that a context is considered recent
|
||||||
@callback
|
@callback
|
||||||
def async_setup(hass: HomeAssistant) -> None:
|
def async_setup(hass: HomeAssistant) -> None:
|
||||||
"""Set up entity sources."""
|
"""Set up entity sources."""
|
||||||
hass.data[DATA_ENTITY_SOURCE] = {}
|
entity_sources(hass)
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
@bind_hass
|
@bind_hass
|
||||||
|
@singleton.singleton(DATA_ENTITY_SOURCE)
|
||||||
def entity_sources(hass: HomeAssistant) -> dict[str, EntityInfo]:
|
def entity_sources(hass: HomeAssistant) -> dict[str, EntityInfo]:
|
||||||
"""Get the entity sources."""
|
"""Get the entity sources."""
|
||||||
_entity_sources: dict[str, EntityInfo] = hass.data[DATA_ENTITY_SOURCE]
|
return {}
|
||||||
return _entity_sources
|
|
||||||
|
|
||||||
|
|
||||||
def generate_entity_id(
|
def generate_entity_id(
|
||||||
|
@ -1486,7 +1486,7 @@ class Entity(
|
||||||
# The check for self.platform guards against integrations not using an
|
# The check for self.platform guards against integrations not using an
|
||||||
# EntityComponent and can be removed in HA Core 2024.1
|
# EntityComponent and can be removed in HA Core 2024.1
|
||||||
if self.platform:
|
if self.platform:
|
||||||
self.hass.data[DATA_ENTITY_SOURCE].pop(self.entity_id)
|
entity_sources(self.hass).pop(self.entity_id)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _async_registry_updated(
|
def _async_registry_updated(
|
||||||
|
|
|
@ -25,6 +25,7 @@ def singleton(data_key: str) -> Callable[[_FuncType[_T]], _FuncType[_T]]:
|
||||||
"""Wrap a function with caching logic."""
|
"""Wrap a function with caching logic."""
|
||||||
if not asyncio.iscoroutinefunction(func):
|
if not asyncio.iscoroutinefunction(func):
|
||||||
|
|
||||||
|
@functools.lru_cache(maxsize=1)
|
||||||
@bind_hass
|
@bind_hass
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def wrapped(hass: HomeAssistant) -> _T:
|
def wrapped(hass: HomeAssistant) -> _T:
|
||||||
|
|
|
@ -24,6 +24,8 @@ from homeassistant.loader import (
|
||||||
)
|
)
|
||||||
from homeassistant.util.json import load_json
|
from homeassistant.util.json import load_json
|
||||||
|
|
||||||
|
from . import singleton
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
TRANSLATION_FLATTEN_CACHE = "translation_flatten_cache"
|
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:
|
def _async_get_translations_cache(hass: HomeAssistant) -> _TranslationCache:
|
||||||
"""Return the translation cache."""
|
"""Return the translation cache."""
|
||||||
cache: _TranslationCache = hass.data[TRANSLATION_FLATTEN_CACHE]
|
return _TranslationCache(hass)
|
||||||
return cache
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
|
@ -385,7 +386,7 @@ def async_setup(hass: HomeAssistant) -> None:
|
||||||
"""
|
"""
|
||||||
cache = _TranslationCache(hass)
|
cache = _TranslationCache(hass)
|
||||||
current_language = hass.config.language
|
current_language = hass.config.language
|
||||||
hass.data[TRANSLATION_FLATTEN_CACHE] = cache
|
_async_get_translations_cache(hass)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _async_load_translations_filter(event_data: Mapping[str, Any]) -> bool:
|
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 .core import HomeAssistant, callback
|
||||||
from .exceptions import HomeAssistantError
|
from .exceptions import HomeAssistantError
|
||||||
|
from .helpers import singleton
|
||||||
from .helpers.typing import UNDEFINED, UndefinedType
|
from .helpers.typing import UNDEFINED, UndefinedType
|
||||||
from .loader import Integration, IntegrationNotFound, async_get_integration
|
from .loader import Integration, IntegrationNotFound, async_get_integration
|
||||||
from .util import package as pkg_util
|
from .util import package as pkg_util
|
||||||
|
@ -72,14 +73,10 @@ async def async_load_installed_versions(
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
|
@singleton.singleton(DATA_REQUIREMENTS_MANAGER)
|
||||||
def _async_get_manager(hass: HomeAssistant) -> RequirementsManager:
|
def _async_get_manager(hass: HomeAssistant) -> RequirementsManager:
|
||||||
"""Get the requirements manager."""
|
"""Get the requirements manager."""
|
||||||
if DATA_REQUIREMENTS_MANAGER in hass.data:
|
return RequirementsManager(hass)
|
||||||
manager: RequirementsManager = hass.data[DATA_REQUIREMENTS_MANAGER]
|
|
||||||
return manager
|
|
||||||
|
|
||||||
manager = hass.data[DATA_REQUIREMENTS_MANAGER] = RequirementsManager(hass)
|
|
||||||
return manager
|
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
|
|
|
@ -29,7 +29,7 @@ from .core import (
|
||||||
callback,
|
callback,
|
||||||
)
|
)
|
||||||
from .exceptions import DependencyError, HomeAssistantError
|
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.issue_registry import IssueSeverity, async_create_issue
|
||||||
from .helpers.typing import ConfigType
|
from .helpers.typing import ConfigType
|
||||||
from .util.async_ import create_eager_task
|
from .util.async_ import create_eager_task
|
||||||
|
@ -671,13 +671,12 @@ class SetupPhases(StrEnum):
|
||||||
"""Wait time for the packages to import."""
|
"""Wait time for the packages to import."""
|
||||||
|
|
||||||
|
|
||||||
|
@singleton.singleton(DATA_SETUP_STARTED)
|
||||||
def _setup_started(
|
def _setup_started(
|
||||||
hass: core.HomeAssistant,
|
hass: core.HomeAssistant,
|
||||||
) -> dict[tuple[str, str | None], float]:
|
) -> dict[tuple[str, str | None], float]:
|
||||||
"""Return the setup started dict."""
|
"""Return the setup started dict."""
|
||||||
if DATA_SETUP_STARTED not in hass.data:
|
return {}
|
||||||
hass.data[DATA_SETUP_STARTED] = {}
|
|
||||||
return hass.data[DATA_SETUP_STARTED] # type: ignore[no-any-return]
|
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
|
@ -717,15 +716,12 @@ def async_pause_setup(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@singleton.singleton(DATA_SETUP_TIME)
|
||||||
def _setup_times(
|
def _setup_times(
|
||||||
hass: core.HomeAssistant,
|
hass: core.HomeAssistant,
|
||||||
) -> defaultdict[str, defaultdict[str | None, defaultdict[SetupPhases, float]]]:
|
) -> defaultdict[str, defaultdict[str | None, defaultdict[SetupPhases, float]]]:
|
||||||
"""Return the setup timings default dict."""
|
"""Return the setup timings default dict."""
|
||||||
if DATA_SETUP_TIME not in hass.data:
|
return defaultdict(lambda: defaultdict(lambda: defaultdict(float)))
|
||||||
hass.data[DATA_SETUP_TIME] = defaultdict(
|
|
||||||
lambda: defaultdict(lambda: defaultdict(float))
|
|
||||||
)
|
|
||||||
return hass.data[DATA_SETUP_TIME] # type: ignore[no-any-return]
|
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
|
|
Loading…
Add table
Reference in a new issue