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

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
pull/40794/head
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
1 changed files with 8 additions and 9 deletions

View File

@ -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):