From 38b410bd88bedcf5904ebfaf8680f4865dacc2a7 Mon Sep 17 00:00:00 2001 From: Rob Jarawan <32302742+robjarawan@users.noreply.github.com> Date: Sun, 29 Mar 2026 21:33:04 -0400 Subject: [PATCH] Fix MQTT close() blocking indefinitely on pending publishes The while loop waiting for pending_publishes to drain has no upper bound. If the broker never acks, close() hangs forever with EBO capped at 64s. Add a max_wait bound (uses timeout setting, default 300s) so close() eventually gives up and proceeds with disconnect. --- sarracenia/moth/mqtt.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/sarracenia/moth/mqtt.py b/sarracenia/moth/mqtt.py index 909b6fe43..15413a071 100644 --- a/sarracenia/moth/mqtt.py +++ b/sarracenia/moth/mqtt.py @@ -834,17 +834,24 @@ def close(self): time.sleep(0.1) if hasattr(self, 'pending_publishes'): - ebo=0.1 - while len(self.pending_publishes) >0: - logger.info( f'waiting {ebo} seconds for last {len(self.pending_publishes)} messages to publish') + ebo = 0.1 + total_wait = 0 + max_wait = self.o['timeout'] if self.o.get('timeout') else 300 + while len(self.pending_publishes) > 0: + if total_wait >= max_wait: + logger.warning(f'gave up waiting for {len(self.pending_publishes)} pending publishes after {total_wait:.0f}s') + break + logger.info(f'waiting {ebo} seconds for last {len(self.pending_publishes)} messages to publish') if len(self.unexpected_publishes) < 10: - logger.info( f'messages acknowledged before publish?: {self.unexpected_publishes}') + logger.info(f'messages acknowledged before publish?: {self.unexpected_publishes}') if len(self.pending_publishes) < 10: - logger.info( f'messages awaiting publish: {self.pending_publishes}') + logger.info(f'messages awaiting publish: {self.pending_publishes}') time.sleep(ebo) + total_wait += ebo if ebo < 64: ebo *= 2 - logger.info('no more pending messages') + else: + logger.info('no more pending messages') self.client.disconnect() self.client.loop_stop() self.connected=False