async def _async_set_up_integrations(hass: core.HomeAssistant, config: Dict[str, Any]) -> None: """Set up all the integrations.""" setup_started = hass.data[DATA_SETUP_STARTED] = {} domains_to_setup = _get_domains(hass, config) # Resolve all dependencies so we know all integrations # that will have to be loaded and start rightaway integration_cache: Dict[str, loader.Integration] = {} to_resolve = domains_to_setup while to_resolve: old_to_resolve = to_resolve to_resolve = set() integrations_to_process = [ int_or_exc for int_or_exc in await gather_with_concurrency( loader.MAX_LOAD_CONCURRENTLY, *(loader.async_get_integration(hass, domain) for domain in old_to_resolve), return_exceptions=True, ) if isinstance(int_or_exc, loader.Integration) ] resolve_dependencies_tasks = [ itg.resolve_dependencies() for itg in integrations_to_process if not itg.all_dependencies_resolved ] if resolve_dependencies_tasks: await asyncio.gather(*resolve_dependencies_tasks) for itg in integrations_to_process: integration_cache[itg.domain] = itg for dep in itg.all_dependencies: if dep in domains_to_setup: continue domains_to_setup.add(dep) to_resolve.add(dep) _LOGGER.info("Domains to be set up: %s", domains_to_setup) logging_domains = domains_to_setup & LOGGING_INTEGRATIONS # Load logging as soon as possible if logging_domains: _LOGGER.info("Setting up logging: %s", logging_domains) await async_setup_multi_components(hass, logging_domains, config, setup_started) # Start up debuggers. Start these first in case they want to wait. debuggers = domains_to_setup & DEBUGGER_INTEGRATIONS if debuggers: _LOGGER.debug("Setting up debuggers: %s", debuggers) await async_setup_multi_components(hass, debuggers, config, setup_started) # calculate what components to setup in what stage stage_1_domains = set() # Find all dependencies of any dependency of any stage 1 integration that # we plan on loading and promote them to stage 1 deps_promotion = STAGE_1_INTEGRATIONS while deps_promotion: old_deps_promotion = deps_promotion deps_promotion = set() for domain in old_deps_promotion: if domain not in domains_to_setup or domain in stage_1_domains: continue stage_1_domains.add(domain) dep_itg = integration_cache.get(domain) if dep_itg is None: continue deps_promotion.update(dep_itg.all_dependencies) stage_2_domains = domains_to_setup - logging_domains - debuggers - stage_1_domains # Kick off loading the registries. They don't need to be awaited. asyncio.create_task(hass.helpers.device_registry.async_get_registry()) asyncio.create_task(hass.helpers.entity_registry.async_get_registry()) asyncio.create_task(hass.helpers.area_registry.async_get_registry()) # Start setup if stage_1_domains: _LOGGER.info("Setting up stage 1: %s", stage_1_domains) try: async with hass.timeout.async_timeout(STAGE_1_TIMEOUT, cool_down=COOLDOWN_TIME): await async_setup_multi_components(hass, stage_1_domains, config, setup_started) except asyncio.TimeoutError: _LOGGER.warning("Setup timed out for stage 1 - moving forward") # Enables after dependencies async_set_domains_to_be_loaded(hass, stage_1_domains | stage_2_domains) if stage_2_domains: _LOGGER.info("Setting up stage 2: %s", stage_2_domains) try: async with hass.timeout.async_timeout(STAGE_2_TIMEOUT, cool_down=COOLDOWN_TIME): await async_setup_multi_components(hass, stage_2_domains, config, setup_started) except asyncio.TimeoutError: _LOGGER.warning("Setup timed out for stage 2 - moving forward") # Wrap up startup _LOGGER.debug("Waiting for startup to wrap up") try: async with hass.timeout.async_timeout(WRAP_UP_TIMEOUT, cool_down=COOLDOWN_TIME): await hass.async_block_till_done() except asyncio.TimeoutError: _LOGGER.warning("Setup timed out for bootstrap - moving forward")
area_registry.async_load(hass), ) # Start setup if stage_1_domains: _LOGGER.info("Setting up stage 1: %s", stage_1_domains) try: async with hass.timeout.async_timeout(STAGE_1_TIMEOUT, cool_down=COOLDOWN_TIME): await async_setup_multi_components(hass, stage_1_domains, config) except asyncio.TimeoutError: _LOGGER.warning("Setup timed out for stage 1 - moving forward") # Enables after dependencies async_set_domains_to_be_loaded(hass, stage_2_domains) if stage_2_domains: _LOGGER.info("Setting up stage 2: %s", stage_2_domains) try: async with hass.timeout.async_timeout(STAGE_2_TIMEOUT, cool_down=COOLDOWN_TIME): await async_setup_multi_components(hass, stage_2_domains, config) except asyncio.TimeoutError: _LOGGER.warning("Setup timed out for stage 2 - moving forward") # Wrap up startup _LOGGER.debug("Waiting for startup to wrap up") try: async with hass.timeout.async_timeout(WRAP_UP_TIMEOUT,