Preload platform integrations to better group executor usage (#112010)
parent
c8cb0ff61d
commit
6a243d6705
|
@ -675,6 +675,9 @@ async def _async_resolve_domains_to_setup(
|
|||
base_platforms_loaded = False
|
||||
domains_to_setup = _get_domains(hass, config)
|
||||
needed_requirements: set[str] = set()
|
||||
platform_integrations = conf_util.extract_platform_integrations(
|
||||
config, BASE_PLATFORMS
|
||||
)
|
||||
|
||||
# Resolve all dependencies so we know all integrations
|
||||
# that will have to be loaded and start rightaway
|
||||
|
@ -691,7 +694,7 @@ async def _async_resolve_domains_to_setup(
|
|||
# to avoid the lock contention when multiple
|
||||
# integrations try to resolve them at once
|
||||
base_platforms_loaded = True
|
||||
to_get = {*old_to_resolve, *BASE_PLATFORMS}
|
||||
to_get = {*old_to_resolve, *BASE_PLATFORMS, *platform_integrations}
|
||||
else:
|
||||
to_get = old_to_resolve
|
||||
|
||||
|
@ -700,13 +703,16 @@ async def _async_resolve_domains_to_setup(
|
|||
integrations_to_process: list[loader.Integration] = []
|
||||
|
||||
for domain, itg in (await loader.async_get_integrations(hass, to_get)).items():
|
||||
if not isinstance(itg, loader.Integration) or domain not in old_to_resolve:
|
||||
if not isinstance(itg, loader.Integration):
|
||||
continue
|
||||
integrations_to_process.append(itg)
|
||||
integration_cache[domain] = itg
|
||||
needed_requirements.update(itg.requirements)
|
||||
if domain not in old_to_resolve:
|
||||
continue
|
||||
|
||||
integrations_to_process.append(itg)
|
||||
manifest_deps.update(itg.dependencies)
|
||||
manifest_deps.update(itg.after_dependencies)
|
||||
needed_requirements.update(itg.requirements)
|
||||
if not itg.all_dependencies_resolved:
|
||||
resolve_dependencies_tasks.append(
|
||||
create_eager_task(
|
||||
|
@ -760,7 +766,9 @@ async def _async_resolve_domains_to_setup(
|
|||
# wait for the translation load lock, loading will be done by the
|
||||
# time it gets to it.
|
||||
hass.async_create_background_task(
|
||||
translation.async_load_integrations(hass, {*BASE_PLATFORMS, *domains_to_setup}),
|
||||
translation.async_load_integrations(
|
||||
hass, {*BASE_PLATFORMS, *platform_integrations, *domains_to_setup}
|
||||
),
|
||||
"load translations",
|
||||
eager_start=True,
|
||||
)
|
||||
|
|
|
@ -1388,6 +1388,30 @@ def config_per_platform(
|
|||
yield platform, item
|
||||
|
||||
|
||||
def extract_platform_integrations(config: ConfigType, domains: set[str]) -> set[str]:
|
||||
"""Find all the platforms in a configuration."""
|
||||
platform_integrations: set[str] = set()
|
||||
for key, domain_config in config.items():
|
||||
try:
|
||||
domain = cv.domain_key(key)
|
||||
except vol.Invalid:
|
||||
continue
|
||||
if domain not in domains:
|
||||
continue
|
||||
|
||||
if not isinstance(domain_config, list):
|
||||
domain_config = [domain_config]
|
||||
|
||||
for item in domain_config:
|
||||
try:
|
||||
platform = item.get(CONF_PLATFORM)
|
||||
except AttributeError:
|
||||
continue
|
||||
if platform:
|
||||
platform_integrations.add(platform)
|
||||
return platform_integrations
|
||||
|
||||
|
||||
def extract_domain_configs(config: ConfigType, domain: str) -> Sequence[str]:
|
||||
"""Extract keys from config for given domain name.
|
||||
|
||||
|
|
|
@ -2339,3 +2339,34 @@ def test_config_per_platform() -> None:
|
|||
(None, 1),
|
||||
("hello 2", config["zone Hallo"][1]),
|
||||
] == list(config_util.config_per_platform(config, "zone"))
|
||||
|
||||
|
||||
def test_extract_platform_integrations() -> None:
|
||||
"""Test extract_platform_integrations."""
|
||||
config = OrderedDict(
|
||||
[
|
||||
(b"zone", {"platform": "not str"}),
|
||||
("zone", {"platform": "hello"}),
|
||||
("zonex", []),
|
||||
("zoney", ""),
|
||||
("notzone", {"platform": "nothello"}),
|
||||
("zoner", None),
|
||||
("zone Hallo", [1, {"platform": "hello 2"}]),
|
||||
("zone 100", None),
|
||||
("i n v a-@@", None),
|
||||
("i n v a-@@", {"platform": "hello"}),
|
||||
("zoneq", "pig"),
|
||||
("zoneempty", {"platform": ""}),
|
||||
]
|
||||
)
|
||||
assert config_util.extract_platform_integrations(config, {"zone"}) == {
|
||||
"hello",
|
||||
"hello 2",
|
||||
}
|
||||
assert config_util.extract_platform_integrations(config, {"zonex"}) == set()
|
||||
assert config_util.extract_platform_integrations(config, {"zoney"}) == set()
|
||||
assert config_util.extract_platform_integrations(
|
||||
config, {"zone", "not_valid", "notzone"}
|
||||
) == {"hello", "hello 2", "nothello"}
|
||||
assert config_util.extract_platform_integrations(config, {"zoneq"}) == set()
|
||||
assert config_util.extract_platform_integrations(config, {"zoneempty"}) == set()
|
||||
|
|
Loading…
Reference in New Issue