1
0
mirror of https://github.com/home-assistant/core.git synced 2026-07-12 17:18:04 +01:00

Trim cached websocket event payload once per event instead of per subscriber (#175569)

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Paulus Schoutsen
2026-07-05 00:32:44 +02:00
committed by GitHub
parent 1910dc7e93
commit fa3ededf3c
2 changed files with 24 additions and 8 deletions
@@ -131,7 +131,7 @@ def cached_event_message(message_id_as_bytes: bytes, event: Event) -> bytes:
"""
return b"".join(
(
_partial_cached_event_message(event)[:-1],
_partial_cached_event_message(event),
b',"id":',
message_id_as_bytes,
b"}",
@@ -143,13 +143,14 @@ def cached_event_message(message_id_as_bytes: bytes, event: Event) -> bytes:
def _partial_cached_event_message(event: Event) -> bytes:
"""Cache and serialize the event to json.
The message is constructed without the id which appended
in cached_event_message.
The message is cached without the trailing "}" and without the id, both of
which are appended in cached_event_message. Trimming here means the slice
happens once per event instead of once per subscriber.
"""
return (
_message_to_json_bytes_or_none({"type": "event", "event": event.json_fragment})
or INVALID_JSON_PARTIAL_MESSAGE
)
)[:-1]
def cached_state_diff_message(
@@ -165,7 +166,7 @@ def cached_state_diff_message(
"""
return b"".join(
(
_partial_cached_state_diff_message(event)[:-1],
_partial_cached_state_diff_message(event),
b',"id":',
message_id_as_bytes,
b"}",
@@ -177,15 +178,16 @@ def cached_state_diff_message(
def _partial_cached_state_diff_message(event: Event[EventStateChangedData]) -> bytes:
"""Cache and serialize the event to json.
The message is constructed without the id which
will be appended in cached_state_diff_message
The message is cached without the trailing "}" and without the id, both of
which are appended in cached_state_diff_message. Trimming here means the
slice happens once per event instead of once per subscriber.
"""
return (
_message_to_json_bytes_or_none(
{"type": "event", "event": _state_diff_event(event)}
)
or INVALID_JSON_PARTIAL_MESSAGE
)
)[:-1]
def _state_diff_event(
@@ -10,6 +10,7 @@ from homeassistant.components.websocket_api.messages import (
)
from homeassistant.const import EVENT_STATE_CHANGED
from homeassistant.core import Context, Event, HomeAssistant, State, callback
from homeassistant.util.json import json_loads
from tests.common import async_capture_events
@@ -52,6 +53,19 @@ async def test_cached_event_message(hass: HomeAssistant) -> None:
assert cache_info.currsize == 2
async def test_cached_event_message_is_valid_json(hass: HomeAssistant) -> None:
"""Test the cached event message is valid JSON with the id appended."""
events = async_capture_events(hass, EVENT_STATE_CHANGED)
hass.states.async_set("light.window", "on")
await hass.async_block_till_done()
parsed = json_loads(cached_event_message(b"2", events[0]))
assert parsed["id"] == 2
assert parsed["type"] == "event"
assert parsed["event"]["event_type"] == EVENT_STATE_CHANGED
async def test_cached_event_message_with_different_idens(hass: HomeAssistant) -> None:
"""Test that we cache event messages when the subscrition idens differ."""