fix MQTT retry loop race condition with cleanup disconnect

Previously, the reconnection loop was calling client.disconnect() during cleanup,
which triggered the disconnect callback with code 0 ("Normal disconnection").
The callback would then exit early, preventing further reconnection attempts.

This creates a cleanup flag that prevents the disconnect callback from
stopping reconnection when we're intentionally cleaning up the old client
during retry attempts.

Fixes issue where MQTT would get stuck in retry loop without actually
attempting fresh connections.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Daniel 2025-09-14 19:03:34 -04:00
parent 91d3a7b245
commit b0f189056a

View File

@ -24,6 +24,7 @@ class MqttClient(Communicator):
self._reconnect_thread: Optional[threading.Thread] = None
self._reconnect_delay = 10 # Retry every 10 seconds
self._stop_reconnect: bool = False
self._cleanup_in_progress: bool = False
def subscribe(self, receiver: Callable[[str, str], None]) -> None:
"""Wrapper for allowing dispatcher to subscribe."""
@ -239,11 +240,15 @@ class MqttClient(Communicator):
f"MQTT disconnected - reason: '{reason_name}', code: {reason_value}, type: {type(reason_code)}"
)
# Don't attempt reconnection if we're stopping or if it was a clean disconnect
# Don't attempt reconnection if we're stopping, cleaning up, or if it was a clean disconnect
if self._stop_reconnect:
logger.error("MQTT not reconnecting - stop flag set")
return
if self._cleanup_in_progress:
logger.error("MQTT not reconnecting - cleanup in progress")
return
if reason_code == 0:
logger.error("MQTT not reconnecting - clean disconnect (code 0)")
return
@ -379,9 +384,12 @@ class MqttClient(Communicator):
# Clean up old client if it exists
if self.client is not None:
try:
self._cleanup_in_progress = True
self.client.disconnect()
self.client.loop_stop()
self._cleanup_in_progress = False
except Exception:
self._cleanup_in_progress = False
pass # Ignore cleanup errors
# Create completely fresh client and attempt connection