Avoid overloading the executor with service.yaml loads (#42172)
parent
43aaf91799
commit
4a0d18ccd8
|
@ -38,7 +38,7 @@ from homeassistant.helpers import template
|
|||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.template import Template
|
||||
from homeassistant.helpers.typing import ConfigType, HomeAssistantType, TemplateVarsType
|
||||
from homeassistant.loader import async_get_integration, bind_hass
|
||||
from homeassistant.loader import Integration, async_get_integration, bind_hass
|
||||
from homeassistant.util.yaml import load_yaml
|
||||
from homeassistant.util.yaml.loader import JSON_TYPE
|
||||
|
||||
|
@ -252,21 +252,29 @@ async def async_extract_entity_ids(
|
|||
return extracted
|
||||
|
||||
|
||||
async def _load_services_file(hass: HomeAssistantType, domain: str) -> JSON_TYPE:
|
||||
def _load_services_file(hass: HomeAssistantType, integration: Integration) -> JSON_TYPE:
|
||||
"""Load services file for an integration."""
|
||||
integration = await async_get_integration(hass, domain)
|
||||
try:
|
||||
return await hass.async_add_executor_job(
|
||||
load_yaml, str(integration.file_path / "services.yaml")
|
||||
)
|
||||
return load_yaml(str(integration.file_path / "services.yaml"))
|
||||
except FileNotFoundError:
|
||||
_LOGGER.warning("Unable to find services.yaml for the %s integration", domain)
|
||||
_LOGGER.warning(
|
||||
"Unable to find services.yaml for the %s integration", integration.domain
|
||||
)
|
||||
return {}
|
||||
except HomeAssistantError:
|
||||
_LOGGER.warning("Unable to parse services.yaml for the %s integration", domain)
|
||||
_LOGGER.warning(
|
||||
"Unable to parse services.yaml for the %s integration", integration.domain
|
||||
)
|
||||
return {}
|
||||
|
||||
|
||||
def _load_services_files(
|
||||
hass: HomeAssistantType, integrations: Iterable[Integration]
|
||||
) -> List[JSON_TYPE]:
|
||||
"""Load service files for multiple intergrations."""
|
||||
return [_load_services_file(hass, integration) for integration in integrations]
|
||||
|
||||
|
||||
@bind_hass
|
||||
async def async_get_all_descriptions(
|
||||
hass: HomeAssistantType,
|
||||
|
@ -289,8 +297,12 @@ async def async_get_all_descriptions(
|
|||
loaded = {}
|
||||
|
||||
if missing:
|
||||
contents = await asyncio.gather(
|
||||
*(_load_services_file(hass, domain) for domain in missing)
|
||||
integrations = await asyncio.gather(
|
||||
*(async_get_integration(hass, domain) for domain in missing)
|
||||
)
|
||||
|
||||
contents = await hass.async_add_executor_job(
|
||||
_load_services_files, hass, integrations
|
||||
)
|
||||
|
||||
for domain, content in zip(missing, contents):
|
||||
|
@ -308,7 +320,7 @@ async def async_get_all_descriptions(
|
|||
# Cache missing descriptions
|
||||
if description is None:
|
||||
domain_yaml = loaded[domain]
|
||||
yaml_description = domain_yaml.get(service, {})
|
||||
yaml_description = domain_yaml.get(service, {}) # type: ignore
|
||||
|
||||
# Don't warn for missing services, because it triggers false
|
||||
# positives for things like scripts, that register as a service
|
||||
|
|
Loading…
Reference in New Issue