MQTT client doesn't recover after printer disconnect — stuck retrying dead socket #105
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
When the printer drops off the network (e.g. powered off) and comes back later at the same IP, kx-bridge does not reconnect on its own. It gets stuck in a tight loop:
repeating every ~3 seconds indefinitely, even with the printer back online and reachable (confirmed via
pingandnc -zv <ip> 9883succeeding).Root cause appears to be that the reconnect handler doesn't null out / rebuild the socket object before retrying — it keeps calling
.sendall()on a socket reference that's alreadyNone, so the "reconnect" attempt never actually opens a new connection. A full container restart (docker restart) resolves it immediately, with a clean TLS handshake and MQTT CONNACK, confirming this is a bridge-side reconnect bug rather than a network/printer issue.Expected: after a connection loss, the MQTT client should tear down and re-establish a fresh socket/TLS session rather than looping on a stale reference.
Environment:
gitea.it-drui.de/viewit/kx-bridge:latest, digestsha256:cd57bb43364944ba214d45c4c3b3f14ec9828fb0d78300c3e4d8453414d7f3a6Thanks for the excellent report, @p2l — precise repro conditions and the exact log pattern made this straightforward to track down.
Root cause (slightly different from what you suspected, same symptom): there are actually two independent reconnect paths that could race each other — the MQTT reader thread's own reconnect (triggered by a failed keepalive) and a second reconnect triggered from
publish()/publish_web()when a send fails. Neither had any protection against running concurrently, so two threads could end up opening competing TLS handshakes to the printer at once, which likely only accepts one mTLS session at a time — the two attempts interfered with each other and neither ever converged.On top of that, the bridge's own status-poll loop made the problem invisible: it only checked whether the printer was TCP-reachable (a raw connect test on port 9883) to decide if it should attempt reconnecting, not whether the actual MQTT/TLS session was still alive. A
NoneType has no attribute 'sendall'failure insidepublish()gets swallowed internally and returnsNoneinstead of raising — so the poll loop had no way to notice the session was dead and just kept assuming everything was fine.Fix:
Fix is committed on
nightlywith test coverage for both the concurrent-reconnect race and the poll-loop detection gap; will go out with the next nightly build. If you hit this again afterward, a fresh log capture of the same disconnect/reconnect cycle would help confirm it's fully resolved.