mirror of
https://github.com/home-assistant/core.git
synced 2025-04-27 18:57:57 +00:00
Reduce lock contention when all icons are already cached (#109352)
This commit is contained in:
parent
b471b9926d
commit
1c84997c5c
@ -13,7 +13,6 @@ from homeassistant.util.json import load_json_object
|
|||||||
|
|
||||||
from .translation import build_resources
|
from .translation import build_resources
|
||||||
|
|
||||||
ICON_LOAD_LOCK = "icon_load_lock"
|
|
||||||
ICON_CACHE = "icon_cache"
|
ICON_CACHE = "icon_cache"
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -73,13 +72,14 @@ async def _async_get_component_icons(
|
|||||||
class _IconsCache:
|
class _IconsCache:
|
||||||
"""Cache for icons."""
|
"""Cache for icons."""
|
||||||
|
|
||||||
__slots__ = ("_hass", "_loaded", "_cache")
|
__slots__ = ("_hass", "_loaded", "_cache", "_lock")
|
||||||
|
|
||||||
def __init__(self, hass: HomeAssistant) -> None:
|
def __init__(self, hass: HomeAssistant) -> None:
|
||||||
"""Initialize the cache."""
|
"""Initialize the cache."""
|
||||||
self._hass = hass
|
self._hass = hass
|
||||||
self._loaded: set[str] = set()
|
self._loaded: set[str] = set()
|
||||||
self._cache: dict[str, dict[str, Any]] = {}
|
self._cache: dict[str, dict[str, Any]] = {}
|
||||||
|
self._lock = asyncio.Lock()
|
||||||
|
|
||||||
async def async_fetch(
|
async def async_fetch(
|
||||||
self,
|
self,
|
||||||
@ -87,6 +87,12 @@ class _IconsCache:
|
|||||||
components: set[str],
|
components: set[str],
|
||||||
) -> dict[str, dict[str, Any]]:
|
) -> dict[str, dict[str, Any]]:
|
||||||
"""Load resources into the cache."""
|
"""Load resources into the cache."""
|
||||||
|
if components_to_load := components - self._loaded:
|
||||||
|
# Icons are never unloaded so if there are no components to load
|
||||||
|
# we can skip the lock which reduces contention
|
||||||
|
async with self._lock:
|
||||||
|
# Check components to load again, as another task might have loaded
|
||||||
|
# them while we were waiting for the lock.
|
||||||
if components_to_load := components - self._loaded:
|
if components_to_load := components - self._loaded:
|
||||||
await self._async_load(components_to_load)
|
await self._async_load(components_to_load)
|
||||||
|
|
||||||
@ -143,17 +149,15 @@ async def async_get_icons(
|
|||||||
"""Return all icons of integrations.
|
"""Return all icons of integrations.
|
||||||
|
|
||||||
If integration specified, load it for that one; otherwise default to loaded
|
If integration specified, load it for that one; otherwise default to loaded
|
||||||
intgrations.
|
integrations.
|
||||||
"""
|
"""
|
||||||
lock = hass.data.setdefault(ICON_LOAD_LOCK, asyncio.Lock())
|
|
||||||
|
|
||||||
if integrations:
|
if integrations:
|
||||||
components = set(integrations)
|
components = set(integrations)
|
||||||
else:
|
else:
|
||||||
components = {
|
components = {
|
||||||
component for component in hass.config.components if "." not in component
|
component for component in hass.config.components if "." not in component
|
||||||
}
|
}
|
||||||
async with lock:
|
|
||||||
if ICON_CACHE in hass.data:
|
if ICON_CACHE in hass.data:
|
||||||
cache: _IconsCache = hass.data[ICON_CACHE]
|
cache: _IconsCache = hass.data[ICON_CACHE]
|
||||||
else:
|
else:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user