core/homeassistant/components/mqtt/async_client.py

61 lines
1.6 KiB
Python

"""Async wrappings for mqtt client."""
from __future__ import annotations
from functools import lru_cache
from types import TracebackType
from typing import Self
from paho.mqtt.client import Client as MQTTClient
_MQTT_LOCK_COUNT = 7
class NullLock:
"""Null lock."""
@lru_cache(maxsize=_MQTT_LOCK_COUNT)
def __enter__(self) -> Self:
"""Enter the lock."""
return self
@lru_cache(maxsize=_MQTT_LOCK_COUNT)
def __exit__(
self,
exc_type: type[BaseException] | None,
exc_value: BaseException | None,
traceback: TracebackType | None,
) -> None:
"""Exit the lock."""
@lru_cache(maxsize=_MQTT_LOCK_COUNT)
def acquire(self, blocking: bool = False, timeout: int = -1) -> None:
"""Acquire the lock."""
@lru_cache(maxsize=_MQTT_LOCK_COUNT)
def release(self) -> None:
"""Release the lock."""
class AsyncMQTTClient(MQTTClient):
"""Async MQTT Client.
Wrapper around paho.mqtt.client.Client to remove the locking
that is not needed since we are running in an async event loop.
"""
def setup(self) -> None:
"""Set up the client.
All the threading locks are replaced with NullLock
since the client is running in an async event loop
and will never run in multiple threads.
"""
self._in_callback_mutex = NullLock()
self._callback_mutex = NullLock()
self._msgtime_mutex = NullLock()
self._out_message_mutex = NullLock()
self._in_message_mutex = NullLock()
self._reconnect_delay_mutex = NullLock()
self._mid_generate_mutex = NullLock()