ingest: add configurable MQTT write timeout (MQTT_WRITE_TIMEOUT_SECONDS)

Bounds PINGREQ/SUBSCRIBE writes so a stalled write through the Cloudflare
WebSocket proxy can't hang the client. Default 0 (paho's existing no-timeout
behavior); wired through docker-compose. Recommended ~20s when behind a
buffering reverse proxy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alex Vanderpot
2026-06-15 22:25:49 -04:00
parent d0cc83af7d
commit a69138d75b
2 changed files with 5 additions and 0 deletions
+1
View File
@@ -64,6 +64,7 @@ services:
- MQTT_STALE_AFTER_SECONDS=${MQTT_STALE_AFTER_SECONDS:-300}
- MQTT_KEEPALIVE_SECONDS=${MQTT_KEEPALIVE_SECONDS:-30}
- MQTT_PING_TIMEOUT_SECONDS=${MQTT_PING_TIMEOUT_SECONDS:-20}
- MQTT_WRITE_TIMEOUT_SECONDS=${MQTT_WRITE_TIMEOUT_SECONDS:-0}
- MESHCORE_BATCH_FLUSH_SECONDS=${MESHCORE_BATCH_FLUSH_SECONDS:-10}
- MESHCORE_BATCH_MAX_ROWS=${MESHCORE_BATCH_MAX_ROWS:-5000}
- MESHCORE_BATCH_BUFFER=${MESHCORE_BATCH_BUFFER:-50000}
+4
View File
@@ -154,6 +154,10 @@ func (d *Daemon) connectToBroker(broker MQTTBrokerConfig, idx int, maxRetries in
// proxy's buffering/jitter; 10s was tight and produced false
// "pingresp not received" disconnects. Configurable for tuning.
opts.SetPingTimeout(time.Duration(GetEnvIntOrDefault("MQTT_PING_TIMEOUT_SECONDS", 20)) * time.Second)
// Bound writes (PINGREQ/SUBSCRIBE) so a stalled write through the
// Cloudflare WebSocket proxy can't hang the client. 0 (paho default)
// disables it; set MQTT_WRITE_TIMEOUT_SECONDS to enable.
opts.SetWriteTimeout(time.Duration(GetEnvIntOrDefault("MQTT_WRITE_TIMEOUT_SECONDS", 0)) * time.Second)
// Start a fresh session on every (re)connect and resubscribe explicitly in
// the OnConnect handler below. This avoids depending on broker-side session
// persistence — which is exactly what left the client connected-but-