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:
@@ -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."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user