Cache serialize of manifest for loaded integrations (#117965)
* Cache serialize of manifest for loaded integrations The manifest/list and manifest/get websocket apis are called frequently when moving around in the UI. Since the manifest does not change we can make the the serialized version a cached property * reduce * reduce
This commit is contained in:
parent
09e7156d2d
commit
c5cc9801a6
3 changed files with 26 additions and 12 deletions
|
@ -46,10 +46,10 @@ from homeassistant.helpers.json import (
|
|||
ExtendedJSONEncoder,
|
||||
find_paths_unserializable_data,
|
||||
json_bytes,
|
||||
json_fragment,
|
||||
)
|
||||
from homeassistant.helpers.service import async_get_all_descriptions
|
||||
from homeassistant.loader import (
|
||||
Integration,
|
||||
IntegrationNotFound,
|
||||
async_get_integration,
|
||||
async_get_integration_descriptions,
|
||||
|
@ -505,19 +505,15 @@ async def handle_manifest_list(
|
|||
hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any]
|
||||
) -> None:
|
||||
"""Handle integrations command."""
|
||||
wanted_integrations = msg.get("integrations")
|
||||
if wanted_integrations is None:
|
||||
wanted_integrations = async_get_loaded_integrations(hass)
|
||||
|
||||
ints_or_excs = await async_get_integrations(hass, wanted_integrations)
|
||||
integrations: list[Integration] = []
|
||||
ints_or_excs = await async_get_integrations(
|
||||
hass, msg.get("integrations") or async_get_loaded_integrations(hass)
|
||||
)
|
||||
manifest_json_fragments: list[json_fragment] = []
|
||||
for int_or_exc in ints_or_excs.values():
|
||||
if isinstance(int_or_exc, Exception):
|
||||
raise int_or_exc
|
||||
integrations.append(int_or_exc)
|
||||
connection.send_result(
|
||||
msg["id"], [integration.manifest for integration in integrations]
|
||||
)
|
||||
manifest_json_fragments.append(int_or_exc.manifest_json_fragment)
|
||||
connection.send_result(msg["id"], manifest_json_fragments)
|
||||
|
||||
|
||||
@decorators.websocket_command(
|
||||
|
@ -530,9 +526,10 @@ async def handle_manifest_get(
|
|||
"""Handle integrations command."""
|
||||
try:
|
||||
integration = await async_get_integration(hass, msg["integration"])
|
||||
connection.send_result(msg["id"], integration.manifest)
|
||||
except IntegrationNotFound:
|
||||
connection.send_error(msg["id"], const.ERR_NOT_FOUND, "Integration not found")
|
||||
else:
|
||||
connection.send_result(msg["id"], integration.manifest_json_fragment)
|
||||
|
||||
|
||||
@callback
|
||||
|
|
|
@ -39,6 +39,7 @@ from .generated.mqtt import MQTT
|
|||
from .generated.ssdp import SSDP
|
||||
from .generated.usb import USB
|
||||
from .generated.zeroconf import HOMEKIT, ZEROCONF
|
||||
from .helpers.json import json_bytes, json_fragment
|
||||
from .util.hass_dict import HassKey
|
||||
from .util.json import JSON_DECODE_EXCEPTIONS, json_loads
|
||||
|
||||
|
@ -762,6 +763,11 @@ class Integration:
|
|||
self._top_level_files = top_level_files or set()
|
||||
_LOGGER.info("Loaded %s from %s", self.domain, pkg_path)
|
||||
|
||||
@cached_property
|
||||
def manifest_json_fragment(self) -> json_fragment:
|
||||
"""Return manifest as a JSON fragment."""
|
||||
return json_fragment(json_bytes(self.manifest))
|
||||
|
||||
@cached_property
|
||||
def name(self) -> str:
|
||||
"""Return name."""
|
||||
|
|
|
@ -15,6 +15,8 @@ from homeassistant.components import http, hue
|
|||
from homeassistant.components.hue import light as hue_light
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import frame
|
||||
from homeassistant.helpers.json import json_dumps
|
||||
from homeassistant.util.json import json_loads
|
||||
|
||||
from .common import MockModule, async_get_persistent_notifications, mock_integration
|
||||
|
||||
|
@ -1959,3 +1961,12 @@ async def test_hass_helpers_use_reported(
|
|||
"Detected that custom integration 'test_integration_frame' "
|
||||
"accesses hass.helpers.aiohttp_client. This is deprecated"
|
||||
) in caplog.text
|
||||
|
||||
|
||||
async def test_manifest_json_fragment_round_trip(hass: HomeAssistant) -> None:
|
||||
"""Test json_fragment roundtrip."""
|
||||
integration = await loader.async_get_integration(hass, "hue")
|
||||
assert (
|
||||
json_loads(json_dumps(integration.manifest_json_fragment))
|
||||
== integration.manifest
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue