From 3d8a1109085d41d959a4e5d756b002ab2a1c63fe Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 3 Apr 2024 09:36:57 -1000 Subject: [PATCH] Dispatch the same ReceiveMessage object if the subscription topic is the same (#114769) --- homeassistant/components/mqtt/client.py | 20 ++++++++++++++------ homeassistant/components/mqtt/models.py | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/mqtt/client.py b/homeassistant/components/mqtt/client.py index b2fab355c41..83830de4963 100644 --- a/homeassistant/components/mqtt/client.py +++ b/homeassistant/components/mqtt/client.py @@ -835,6 +835,7 @@ class MQTT: timestamp = dt_util.utcnow() subscriptions = self._matching_subscriptions(topic) + msg_cache_by_subscription_topic: dict[str, ReceiveMessage] = {} for subscription in subscriptions: if msg.retain: @@ -858,17 +859,24 @@ class MQTT: subscription.job, ) continue - self.hass.async_run_hass_job( - subscription.job, - ReceiveMessage( + subscription_topic = subscription.topic + if subscription_topic not in msg_cache_by_subscription_topic: + # Only make one copy of the message + # per topic so we avoid storing a separate + # dataclass in memory for each subscriber + # to the same topic for retained messages + receive_msg = ReceiveMessage( topic, payload, msg.qos, msg.retain, - subscription.topic, + subscription_topic, timestamp, - ), - ) + ) + msg_cache_by_subscription_topic[subscription_topic] = receive_msg + else: + receive_msg = msg_cache_by_subscription_topic[subscription_topic] + self.hass.async_run_hass_job(subscription.job, receive_msg) self._mqtt_data.state_write_requests.process_write_state_requests(msg) def _mqtt_on_callback( diff --git a/homeassistant/components/mqtt/models.py b/homeassistant/components/mqtt/models.py index 6e6ae784eec..f53643268e7 100644 --- a/homeassistant/components/mqtt/models.py +++ b/homeassistant/components/mqtt/models.py @@ -58,7 +58,7 @@ class PublishMessage: retain: bool -@dataclass +@dataclass(slots=True, frozen=True) class ReceiveMessage: """MQTT Message received."""