From 9fd10da3e541df4ac5298f8e6b40aa395f1b50e7 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 20 Sep 2020 08:55:42 -0500 Subject: [PATCH 1/5] Create MQTTMatcher once per subscription instead of each message --- homeassistant/components/mqtt/__init__.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index bafbead96d66a5..fff471c3554845 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -630,6 +630,7 @@ class Subscription: """Class to hold data about an active subscription.""" topic: str = attr.ib() + matcher: Any = attr.ib() callback: MessageCallbackType = attr.ib() qos: int = attr.ib(default=0) encoding: str = attr.ib(default="utf-8") @@ -838,7 +839,9 @@ async def async_subscribe( if not isinstance(topic, str): raise HomeAssistantError("Topic needs to be a string!") - subscription = Subscription(topic, msg_callback, qos, encoding) + subscription = Subscription( + topic, _matcher_for_topic(topic), msg_callback, qos, encoding + ) self.subscriptions.append(subscription) # Only subscribe if currently connected. @@ -953,7 +956,9 @@ def _mqtt_handle_message(self, msg) -> None: timestamp = dt_util.utcnow() for subscription in self.subscriptions: - if not _match_topic(subscription.topic, msg.topic): + try: + next(subscription.matcher.iter_match(msg.topic)) + except StopIteration: continue payload: SubscribePayloadType = msg.payload @@ -1050,18 +1055,14 @@ def _raise_on_error(result_code: int) -> None: ) -def _match_topic(subscription: str, topic: str) -> bool: - """Test if topic matches subscription.""" +def _matcher_for_topic(topic: str) -> Any: # pylint: disable=import-outside-toplevel from paho.mqtt.matcher import MQTTMatcher matcher = MQTTMatcher() - matcher[subscription] = True - try: - next(matcher.iter_match(topic)) - return True - except StopIteration: - return False + matcher[topic] = True + + return matcher class MqttAttributes(Entity): From 8302c2ef79178f8cecff85b23b975ec1192a9f15 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 30 Sep 2020 07:58:48 -0500 Subject: [PATCH 2/5] Update homeassistant/components/mqtt/__init__.py Co-authored-by: Paulus Schoutsen --- homeassistant/components/mqtt/__init__.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index fff471c3554845..5aa758af52a8d5 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -956,9 +956,7 @@ def _mqtt_handle_message(self, msg) -> None: timestamp = dt_util.utcnow() for subscription in self.subscriptions: - try: - next(subscription.matcher.iter_match(msg.topic)) - except StopIteration: + if not subscription.matcher(msg.topic): continue payload: SubscribePayloadType = msg.payload From 1c77145161c0709b0d053a41491492290869f472 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 30 Sep 2020 07:58:55 -0500 Subject: [PATCH 3/5] Update homeassistant/components/mqtt/__init__.py Co-authored-by: Paulus Schoutsen --- homeassistant/components/mqtt/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 5aa758af52a8d5..939e89d20d3657 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -1060,7 +1060,7 @@ def _matcher_for_topic(topic: str) -> Any: matcher = MQTTMatcher() matcher[topic] = True - return matcher + return lambda topic: next(subscription.matcher.iter_match(msg.topic), False) class MqttAttributes(Entity): From 40c0b8101b08610db97d8ba101bcad7717bd541a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 30 Sep 2020 15:17:15 +0200 Subject: [PATCH 4/5] Update homeassistant/components/mqtt/__init__.py --- homeassistant/components/mqtt/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 939e89d20d3657..446b7377cc28a7 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -1060,7 +1060,7 @@ def _matcher_for_topic(topic: str) -> Any: matcher = MQTTMatcher() matcher[topic] = True - return lambda topic: next(subscription.matcher.iter_match(msg.topic), False) + return lambda topic: next(matcher.iter_match(topic), False) class MqttAttributes(Entity): From d91e0d3c0a8c9960cd955f3076312e4e35cdbc9d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 30 Sep 2020 15:20:29 +0200 Subject: [PATCH 5/5] Apply suggestions from code review --- homeassistant/components/mqtt/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 446b7377cc28a7..b3de8d53a375e3 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -1053,12 +1053,12 @@ def _raise_on_error(result_code: int) -> None: ) -def _matcher_for_topic(topic: str) -> Any: +def _matcher_for_topic(subscription: str) -> Any: # pylint: disable=import-outside-toplevel from paho.mqtt.matcher import MQTTMatcher matcher = MQTTMatcher() - matcher[topic] = True + matcher[subscription] = True return lambda topic: next(matcher.iter_match(topic), False)