Bound MQTT broker operations with a per-node timeout

Without one, aiomqtt's disconnect acknowledgement has no deadline, so a
subscriber cancelled while its socket is dead never finishes unwinding and
teardown abandons the task. The knob is per node because brokers differ.
This commit is contained in:
2026-08-28 11:46:40 +02:00
parent 93e45274d0
commit 192999f178
2 changed files with 46 additions and 0 deletions
+30
View File
@@ -89,3 +89,33 @@ def test_a_string_goes_on_the_wire_bare():
asyncio.run(node._publish_with(client, {"plug": "ON", "level": 60}))
assert client.published == [("actor/plug", "ON"), ("light/level", "60")]
def test_the_configured_timeout_reaches_the_broker_client(monkeypatch):
"""Without one, a dead socket makes the disconnect ack wait forever."""
import aiomqtt
seen: dict = {}
class FakeClient:
def __init__(self, **kwargs):
seen.update(kwargs)
async def __aenter__(self):
return self
async def __aexit__(self, *_):
return False
async def publish(self, *_, **__):
return None
monkeypatch.setattr(aiomqtt, "Client", FakeClient)
node = MqttNode(
requires=[MessageSpec(name="setpoint", port="setpoint", dtype=DType.FLOAT)],
params={"topic": {"setpoint": "heating/setpoint"}, "timeout": 2.5},
)
asyncio.run(node._publish_once({"setpoint": 21.0}))
assert seen["timeout"] == 2.5