Package: python3-hbmqtt
Version: 0.9.6-1.1
Severity: grave
Justification: hbmqtt.client.MQTTClient.connect never works
Tags: patch upstream
The MQTTClient is not useable at all at present. Trying to connect to
any broker results in the following:
| Unhandled exception: 'Lock' object is not iterable
| Connection failed: TypeError("'Lock' object is not iterable")
| Unhandled exception: 'Lock' object is not iterable
| Reconnection attempt failed: TypeError("'Lock' object is not iterable")
| Unhandled exception: 'Lock' object is not iterable
| Reconnection attempt failed: TypeError("'Lock' object is not iterable")
| Unhandled exception: 'Lock' object is not iterable
| Reconnection attempt failed: TypeError("'Lock' object is not iterable")
| Maximum number of connection attempts reached. Reconnection aborted
| Traceback (most recent call last):
| File "/usr/lib/python3/dist-packages/hbmqtt/client.py", line 149, in connect
| return (yield from self._do_connect())
| File "/usr/lib/python3/dist-packages/hbmqtt/client.py", line 234, in
_do_connect
| return_code = yield from self._connect_coro()
| File "/usr/lib/python3/dist-packages/hbmqtt/client.py", line 423, in
_connect_coro
| return_code = yield from self._handler.mqtt_connect()
| File
"/usr/lib/python3/dist-packages/hbmqtt/mqtt/protocol/client_handler.py", line
83, in mqtt_connect
| yield from self._send_packet(connect_packet)
| File "/usr/lib/python3/dist-packages/hbmqtt/mqtt/protocol/handler.py", line
445, in _send_packet
| with (yield from self._write_lock):
| TypeError: 'Lock' object is not iterable
|
| During handling of the above exception, another exception occurred:
|
| Traceback (most recent call last):
| File "/usr/lib/python3/dist-packages/hbmqtt/client.py", line 220, in
reconnect
| return (yield from self._do_connect())
| File "/usr/lib/python3/dist-packages/hbmqtt/client.py", line 234, in
_do_connect
| return_code = yield from self._connect_coro()
| File "/usr/lib/python3/dist-packages/hbmqtt/client.py", line 423, in
_connect_coro
| return_code = yield from self._handler.mqtt_connect()
| File
"/usr/lib/python3/dist-packages/hbmqtt/mqtt/protocol/client_handler.py", line
83, in mqtt_connect
| yield from self._send_packet(connect_packet)
| File "/usr/lib/python3/dist-packages/hbmqtt/mqtt/protocol/handler.py", line
445, in _send_packet
| with (yield from self._write_lock):
| TypeError: 'Lock' object is not iterable
|
| During handling of the above exception, another exception occurred:
|
| Traceback (most recent call last):
| File "<string>", line 1, in <module>
| File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in
run_until_complete
| return future.result()
| File "/usr/lib/python3/dist-packages/hbmqtt/client.py", line 156, in connect
| return (yield from self.reconnect())
| File "/usr/lib/python3/dist-packages/hbmqtt/client.py", line 225, in
reconnect
| raise ConnectException("Too many connection attempts failed")
| hbmqtt.client.ConnectException: Too many connection attempts failed
The cause for this is a change in how asyncio Locks work. Their support
for the pre-async API based on iterators has ceased, but hbmqtt attempts
to do so. Avoiding the context manager does the trick here. Please find
a minimal patch fixing the problem attached.
In any case, hbmqtt looks quite dead upstream. Maybe replacing it with
https://github.com/sbtinstruments/asyncio-mqtt would be better.
Helmut
--- a/hbmqtt/mqtt/protocol/handler.py
+++ b/hbmqtt/mqtt/protocol/handler.py
@@ -442,8 +442,11 @@ class ProtocolHandler:
@asyncio.coroutine
def _send_packet(self, packet):
try:
- with (yield from self._write_lock):
+ yield from self._write_lock.acquire()
+ try:
yield from packet.to_stream(self.writer)
+ finally:
+ self._write_lock.release()
if self._keepalive_task:
self._keepalive_task.cancel()
self._keepalive_task = self._loop.call_later(self.keepalive_timeout, self.handle_write_timeout)