From a11fd08d20fe8e6100cbad0b9c344d0afa7b59fa Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 30 Sep 2020 10:18:43 -0500 Subject: [PATCH] Create MQTTMatcher once per subscription instead of each message (#40345) Co-authored-by: Paulus Schoutsen --- homeassistant/components/mqtt/__init__.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 1d924a40963..74a664532df 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 @@ class MQTT: 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,7 @@ class MQTT: timestamp = dt_util.utcnow() for subscription in self.subscriptions: - if not _match_topic(subscription.topic, msg.topic): + if not subscription.matcher(msg.topic): continue payload: SubscribePayloadType = msg.payload @@ -1050,18 +1053,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(subscription: 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 + + return lambda topic: next(matcher.iter_match(topic), False) class MqttAttributes(Entity):