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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user