Create MQTTMatcher once per subscription instead of each message (#40345)

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
This commit is contained in:
J. Nick Koston 2020-09-30 10:18:43 -05:00 committed by GitHub
parent 4c157f65ea
commit a11fd08d20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -630,6 +630,7 @@ class Subscription:
"""Class to hold data about an active subscription.""" """Class to hold data about an active subscription."""
topic: str = attr.ib() topic: str = attr.ib()
matcher: Any = attr.ib()
callback: MessageCallbackType = attr.ib() callback: MessageCallbackType = attr.ib()
qos: int = attr.ib(default=0) qos: int = attr.ib(default=0)
encoding: str = attr.ib(default="utf-8") encoding: str = attr.ib(default="utf-8")
@ -838,7 +839,9 @@ class MQTT:
if not isinstance(topic, str): if not isinstance(topic, str):
raise HomeAssistantError("Topic needs to be a string!") 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) self.subscriptions.append(subscription)
# Only subscribe if currently connected. # Only subscribe if currently connected.
@ -953,7 +956,7 @@ class MQTT:
timestamp = dt_util.utcnow() timestamp = dt_util.utcnow()
for subscription in self.subscriptions: for subscription in self.subscriptions:
if not _match_topic(subscription.topic, msg.topic): if not subscription.matcher(msg.topic):
continue continue
payload: SubscribePayloadType = msg.payload payload: SubscribePayloadType = msg.payload
@ -1050,18 +1053,14 @@ def _raise_on_error(result_code: int) -> None:
) )
def _match_topic(subscription: str, topic: str) -> bool: def _matcher_for_topic(subscription: str) -> Any:
"""Test if topic matches subscription."""
# pylint: disable=import-outside-toplevel # pylint: disable=import-outside-toplevel
from paho.mqtt.matcher import MQTTMatcher from paho.mqtt.matcher import MQTTMatcher
matcher = MQTTMatcher() matcher = MQTTMatcher()
matcher[subscription] = True matcher[subscription] = True
try:
next(matcher.iter_match(topic)) return lambda topic: next(matcher.iter_match(topic), False)
return True
except StopIteration:
return False
class MqttAttributes(Entity): class MqttAttributes(Entity):