Priority: high — this is the only failure in the async path that produces no error at all.
If an MQTT connection drops mid-run, paho reconnects on its own, but the subscription does not
come back and we never re-subscribe. The adapter believes it is listening, the broker has no
subscription, and the channel goes quiet. A receive then times out looking exactly like "nobody
sent anything".
Cause — both halves verified:
newPahoClient sets CleanSession: true, so paho's reconnect path runs c.persist.Reset()
instead of c.resume(...) (paho v1.5.1 client.go:290-294). No subscription is restored.
(ResumeSubs also defaults to false.)
ensureSubscribed (internal/runner/executor/adapter_mqtt.go) then sees IsConnected() == true,
skips the connect branch, finds subscribed[channel] still true, and returns without
re-subscribing.
A probe against the fake client confirms it: connectCalls goes 1 → 2 while subscribeCalls
stays at 1.
Note: the failed-connect path was fixed separately (the client is dropped and subscribed
cleared). This is the succeeded-after-a-drop path, which that fix does not cover.
Likelihood: needs a real mid-run disconnect — long workflows, long receive timeouts, flaky
networks, broker restarts, or public brokers that drop idle connections. Phase 14 widens this a
lot, since receives will stay in flight for their whole timeout. Worth fixing before then.
Candidate fixes:
- clear
subscribed from a SetOnConnectHandler (fires on reconnects too) — smallest change
- track a connection generation and re-subscribe when it changes
- switch to
CleanSession(false) + ResumeSubs(true) and let the broker keep the session —
changes session semantics, needs its own decision
WebSocket is unaffected: dropConn forgets a broken connection entirely, so the next use
redials and starts a fresh reader.
Priority: high — this is the only failure in the async path that produces no error at all.
If an MQTT connection drops mid-run, paho reconnects on its own, but the subscription does not
come back and we never re-subscribe. The adapter believes it is listening, the broker has no
subscription, and the channel goes quiet. A receive then times out looking exactly like "nobody
sent anything".
Cause — both halves verified:
newPahoClientsetsCleanSession: true, so paho's reconnect path runsc.persist.Reset()instead of
c.resume(...)(paho v1.5.1client.go:290-294). No subscription is restored.(
ResumeSubsalso defaults tofalse.)ensureSubscribed(internal/runner/executor/adapter_mqtt.go) then seesIsConnected() == true,skips the connect branch, finds
subscribed[channel]stilltrue, and returns withoutre-subscribing.
A probe against the fake client confirms it:
connectCallsgoes 1 → 2 whilesubscribeCallsstays at 1.
Note: the failed-connect path was fixed separately (the client is dropped and
subscribedcleared). This is the succeeded-after-a-drop path, which that fix does not cover.
Likelihood: needs a real mid-run disconnect — long workflows, long receive timeouts, flaky
networks, broker restarts, or public brokers that drop idle connections. Phase 14 widens this a
lot, since receives will stay in flight for their whole timeout. Worth fixing before then.
Candidate fixes:
subscribedfrom aSetOnConnectHandler(fires on reconnects too) — smallest changeCleanSession(false)+ResumeSubs(true)and let the broker keep the session —changes session semantics, needs its own decision
WebSocket is unaffected:
dropConnforgets a broken connection entirely, so the next useredials and starts a fresh reader.