Limit service description loading to a single thread (#11733)

This commit is contained in:
Anders Melchiorsen 2018-01-19 06:59:03 +01:00 committed by Paulus Schoutsen
parent a9634199e6
commit ce9673b06d

View File

@ -137,30 +137,29 @@ def async_get_all_descriptions(hass):
component_path = path.dirname(get_component(domain).__file__) component_path = path.dirname(get_component(domain).__file__)
return path.join(component_path, 'services.yaml') return path.join(component_path, 'services.yaml')
def load_services_file(yaml_file): def load_services_files(yaml_files):
"""Load and cache a services.yaml file.""" """Load and parse services.yaml files."""
loaded = {}
for yaml_file in yaml_files:
try: try:
yaml_cache[yaml_file] = load_yaml(yaml_file) loaded[yaml_file] = load_yaml(yaml_file)
except FileNotFoundError: except FileNotFoundError:
pass loaded[yaml_file] = {}
return loaded
services = hass.services.async_services() services = hass.services.async_services()
# Load missing files # Load missing files
yaml_cache = {} missing = set()
loading_tasks = []
for domain in services: for domain in services:
yaml_file = domain_yaml_file(domain)
for service in services[domain]: for service in services[domain]:
if format_cache_key(domain, service) not in description_cache: if format_cache_key(domain, service) not in description_cache:
if yaml_file not in yaml_cache: missing.add(domain_yaml_file(domain))
yaml_cache[yaml_file] = {} break
task = hass.async_add_job(load_services_file, yaml_file)
loading_tasks.append(task)
if loading_tasks: if missing:
yield from asyncio.wait(loading_tasks, loop=hass.loop) loaded = yield from hass.async_add_job(load_services_files, missing)
# Build response # Build response
catch_all_yaml_file = domain_yaml_file(ha.DOMAIN) catch_all_yaml_file = domain_yaml_file(ha.DOMAIN)
@ -176,9 +175,9 @@ def async_get_all_descriptions(hass):
# Cache missing descriptions # Cache missing descriptions
if description is None: if description is None:
if yaml_file == catch_all_yaml_file: if yaml_file == catch_all_yaml_file:
yaml_services = yaml_cache[yaml_file].get(domain, {}) yaml_services = loaded[yaml_file].get(domain, {})
else: else:
yaml_services = yaml_cache[yaml_file] yaml_services = loaded[yaml_file]
yaml_description = yaml_services.get(service, {}) yaml_description = yaml_services.get(service, {})
description = description_cache[cache_key] = { description = description_cache[cache_key] = {