From b061e7d1aa5658dd340d4a164a99990b7d8f8083 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 12 May 2024 11:39:20 +0900 Subject: [PATCH] Small speed up to setting up integrations and config entries (#117278) * Small speed up to setting up integration and config entries When profiling tests, I noticed many calls to get_running_loop. In the places where we are already in a coro, pass the existing loop so it does not have to be looked up. I did not do this for places were we are not in a coro since there is risk that an integration could be doing a non-thread-safe call and its better that the code raises when trying to fetch the running loop vs the performance improvement for these cases. * fix merge * missed some --- homeassistant/bootstrap.py | 6 +++++- homeassistant/config_entries.py | 12 ++++++++++-- homeassistant/helpers/entity_platform.py | 8 +++++--- homeassistant/setup.py | 8 ++++++-- tests/conftest.py | 3 ++- 5 files changed, 28 insertions(+), 9 deletions(-) diff --git a/homeassistant/bootstrap.py b/homeassistant/bootstrap.py index 355cf17eb62..f988f55f7c1 100644 --- a/homeassistant/bootstrap.py +++ b/homeassistant/bootstrap.py @@ -427,7 +427,11 @@ async def async_from_config_dict( if not all( await asyncio.gather( *( - create_eager_task(async_setup_component(hass, domain, config)) + create_eager_task( + async_setup_component(hass, domain, config), + name=f"bootstrap setup {domain}", + loop=hass.loop, + ) for domain in CORE_INTEGRATIONS ) ) diff --git a/homeassistant/config_entries.py b/homeassistant/config_entries.py index 18208a31998..8ab74123d02 100644 --- a/homeassistant/config_entries.py +++ b/homeassistant/config_entries.py @@ -1997,7 +1997,11 @@ class ConfigEntries: *( create_eager_task( self._async_forward_entry_setup(entry, platform, False), - name=f"config entry forward setup {entry.title} {entry.domain} {entry.entry_id} {platform}", + name=( + f"config entry forward setup {entry.title} " + f"{entry.domain} {entry.entry_id} {platform}" + ), + loop=self.hass.loop, ) for platform in platforms ) @@ -2050,7 +2054,11 @@ class ConfigEntries: *( create_eager_task( self.async_forward_entry_unload(entry, platform), - name=f"config entry forward unload {entry.title} {entry.domain} {entry.entry_id} {platform}", + name=( + f"config entry forward unload {entry.title} " + f"{entry.domain} {entry.entry_id} {platform}" + ), + loop=self.hass.loop, ) for platform in platforms ) diff --git a/homeassistant/helpers/entity_platform.py b/homeassistant/helpers/entity_platform.py index e49eff331b9..b3194c245aa 100644 --- a/homeassistant/helpers/entity_platform.py +++ b/homeassistant/helpers/entity_platform.py @@ -354,7 +354,7 @@ class EntityPlatform: try: awaitable = async_create_setup_awaitable() if asyncio.iscoroutine(awaitable): - awaitable = create_eager_task(awaitable) + awaitable = create_eager_task(awaitable, loop=hass.loop) async with hass.timeout.async_timeout(SLOW_SETUP_MAX_WAIT, self.domain): await asyncio.shield(awaitable) @@ -536,7 +536,7 @@ class EntityPlatform: event loop and will finish faster if we run them concurrently. """ results: list[BaseException | None] | None = None - tasks = [create_eager_task(coro) for coro in coros] + tasks = [create_eager_task(coro, loop=self.hass.loop) for coro in coros] try: async with self.hass.timeout.async_timeout(timeout, self.domain): results = await asyncio.gather(*tasks, return_exceptions=True) @@ -1035,7 +1035,9 @@ class EntityPlatform: return if tasks := [ - create_eager_task(entity.async_update_ha_state(True)) + create_eager_task( + entity.async_update_ha_state(True), loop=self.hass.loop + ) for entity in self.entities.values() if entity.should_poll ]: diff --git a/homeassistant/setup.py b/homeassistant/setup.py index e5d28a2676b..f0af8efec09 100644 --- a/homeassistant/setup.py +++ b/homeassistant/setup.py @@ -300,7 +300,7 @@ async def _async_setup_component( # If for some reason the background task in bootstrap was too slow # or the integration was added after bootstrap, we will load them here. load_translations_task = create_eager_task( - translation.async_load_integrations(hass, integration_set) + translation.async_load_integrations(hass, integration_set), loop=hass.loop ) # Validate all dependencies exist and there are no circular dependencies if not await integration.resolve_dependencies(): @@ -448,7 +448,11 @@ async def _async_setup_component( *( create_eager_task( entry.async_setup_locked(hass, integration=integration), - name=f"config entry setup {entry.title} {entry.domain} {entry.entry_id}", + name=( + f"config entry setup {entry.title} {entry.domain} " + f"{entry.entry_id}" + ), + loop=hass.loop, ) for entry in entries ) diff --git a/tests/conftest.py b/tests/conftest.py index 420e84fe2b7..3d4d55e696c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -567,7 +567,8 @@ async def hass( await asyncio.gather( *( create_eager_task( - hass.config_entries.async_unload(config_entry.entry_id) + hass.config_entries.async_unload(config_entry.entry_id), + loop=hass.loop, ) for config_entry in loaded_entries )