Files
MeshCore-mqtt-observer/MQTT_STABILITY_REVIEW.md
T
agessaman 98f176c730 Fix MQTT connection stability and CLI responsiveness issues
- Remove blocking delays in main loop (health check, WiFi reconnect)
- Make WiFi initialization fully async and non-blocking
- Optimize token renewal to only disconnect when token expires (60s buffer)
- Fix health check connection state management
- Add comprehensive stability review documentation
2026-01-02 13:36:41 -08:00

5.0 KiB

MQTT Connection Stability & CLI Responsiveness Review

Summary

This document identifies issues in the MQTT codebase that could cause connection instability or unresponsive CLI behavior.

Critical Issues Fixed

1. Blocking Delays in Main Loop FIXED

  • Location: connectToBrokers() line 743, loop() line 475
  • Issue: delay(100) calls block the entire system for 100ms during:
    • Health check reconnections (every 4 hours)
    • WiFi reconnection attempts
  • Impact:
    • Blocks CLI responsiveness
    • Delays mesh radio operations
    • Causes system-wide pauses
  • Fix: Removed blocking delays - disconnect() and connect() are async operations

2. Blocking WiFi Initialization FIXED

  • Location: begin() line 215-219
  • Issue: Blocking delay(500) loop for up to 10 seconds (20 attempts) during WiFi initialization
  • Impact:
    • Blocks system startup
    • Delays mesh radio initialization
    • CLI unresponsive during startup
  • Fix: Removed blocking wait - WiFi connection is now fully asynchronous

3. Token Renewal Disconnection Strategy FIXED (Previous Change)

  • Location: maintainAnalyzerConnections() lines 1947-1958, 2052-2063
  • Issue: Tokens were renewed 1 hour before expiration, causing unnecessary disconnections
  • Impact: Connection drops every 23 hours
  • Fix: Changed to renew only 60 seconds before expiration, only disconnect when token is actually expired

Remaining Issues & Recommendations

4. Static Variable Sharing in Health Check ⚠️ MINOR

  • Location: connectToBrokers() line 727
  • Issue: static unsigned long last_health_check is shared across all brokers
  • Impact: If multi-broker support is added, all brokers will trigger health checks simultaneously
  • Recommendation: Use per-broker health check timestamps (store in broker struct)
  • Priority: Low (current code only supports one broker at a time)

5. NTP Sync Blocking ⚠️ ACCEPTABLE

  • Location: syncTimeWithNTP() line 2178
  • Issue: forceUpdate() is a blocking call that can take several seconds
  • Impact: Blocks main loop during NTP sync (every hour)
  • Status: Acceptable - only happens once per hour, has internal timeout
  • Recommendation: Consider making NTP sync fully async if responsiveness becomes an issue

6. vTaskDelay in Packet Processing ⚠️ ACCEPTABLE

  • Location: processPacketQueue() line 833
  • Issue: vTaskDelay(1) yields for ~10ms on ESP32 after each packet
  • Impact: Adds latency to packet processing
  • Status: Acceptable - prevents blocking, maintains responsiveness
  • Note: This is intentional to yield to other tasks

7. Connection State Race Conditions ⚠️ POTENTIAL

  • Location: Multiple locations checking connected() then using connection
  • Issue: Connection state could change between check and use
  • Impact: Potential for failed publishes or incorrect state tracking
  • Status: Mitigated by async nature of PsychicMqttClient
  • Recommendation: Monitor for any issues, consider adding connection state locks if problems occur

8. Health Check Connection State Management FIXED

  • Location: connectToBrokers() line 754-756
  • Issue: Health check reconnection didn't properly mark broker as disconnected
  • Impact: Could cause state inconsistency
  • Fix: Now properly marks broker as disconnected before async reconnection

Performance Characteristics

Before Fixes

  • WiFi initialization: Up to 10 seconds blocking
  • Health check: 100ms blocking every 4 hours
  • WiFi reconnect: 100ms blocking during reconnect attempts
  • Token renewal: Disconnection every 23 hours (1 hour before expiration)

After Fixes

  • WiFi initialization: Fully async, non-blocking
  • Health check: Fully async, non-blocking
  • WiFi reconnect: Fully async, non-blocking
  • Token renewal: Disconnection only when token expires (within 60 seconds)

Testing Recommendations

  1. Long-term stability test: Run for 24+ hours and monitor:

    • Connection uptime
    • Queue length spikes
    • Status publishing gaps
    • CLI responsiveness
  2. Stress test:

    • Rapid WiFi disconnections/reconnections
    • High packet rate
    • Memory pressure scenarios
  3. CLI responsiveness test:

    • Issue CLI commands during:
      • Token renewal
      • Health check reconnection
      • High packet processing
      • WiFi reconnection

Code Quality Notes

  • All blocking operations have been removed from the main loop
  • Connection operations are now fully asynchronous
  • Token renewal strategy optimized to minimize disconnections
  • Health check properly manages connection state

Future Improvements

  1. Per-broker health check timestamps: Store in broker struct instead of static variable
  2. Async NTP sync: Consider making NTP sync fully async if responsiveness issues occur
  3. Connection state locking: Add locks if race conditions become an issue
  4. Multi-broker support: Implement proper multi-broker support with per-broker state management