Skip to content

Hold back the Expert disconnect notice until a drop actually lasts - #8632

Merged
cstns merged 2 commits into
mainfrom
8630-expert-disconnect-notice-delay
Sep 23, 2026
Merged

cstns merged 2 commits into
mainfrom
8630-expert-disconnect-notice-delay

Conversation

@cstns

@cstns cstns commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Closes #8630

Stacked on #8631, so review that one first.

_onMqttClose posted its message on every close, including drops the client recovered from a second later. "Send another message to pick up where we left off, or start a fresh session" is wrong advice when the connection is about to come back on its own, and the message then sits in the transcript for good.

The close handler now starts a 15s timer and a reconnect cancels it. The _onMqttConnect greeting is gated on the previous message being an error, so suppressing the notice suppresses the greeting along with it and a short drop is silent at both ends. An outage that genuinely lasts still posts once at 15s and still gets its greeting when it recovers.

handleMqttError and startOver clear a pending notice too, the first because it posts a message of its own, the second because the transcript the notice belonged to is about to be cleared.

Worth knowing for review: addPredefinedAiMessage already dedups on errorCode across the last three messages, so a pure close and connect loop was only ever posting one pair rather than one per cycle. This is a correctness fix on a misleading message, not a volume fix. The issue body has the detail.

Five tests added, four of which fail without the change.

reconnectAttempt was cleared on every successful connect, so a link that
connected and then dropped seconds later never backed off and kept retrying at
the initial delay. Record when the connection came up instead, and only clear
the counter once it has held for STABLE_CONNECTION_MS.

_dispatch also invoked observer handlers without catching, so any async handler
that rejected escaped as an unhandled rejection. That is how in-flight packets
flushed by a client teardown surfaced as "Connection closed". It now catches
sync throws and attaches a handler to any promise a handler returns, staying
quiet for teardown errors and warning on everything else.

Also attaches a catch to the fire-and-forget abort publish and gives the
expert:status-message ack the try/catch its sibling branches already have.
_onMqttClose posted "Looks like we got disconnected. Send another message to
pick up where we left off, or start a fresh session." on every close, including
drops the client recovered from a second later. That advice is wrong for a blip,
and the message stays in the transcript for good.

Start a 15s timer instead and let a reconnect cancel it. The "I'm back" greeting
only fires when the previous message was an error, so suppressing the notice
suppresses the greeting with it and a short drop is silent at both ends. A real
outage still posts once at 15s and still gets its greeting on recovery.

handleMqttError and startOver clear a pending notice too: the first posts a
message of its own, the second clears the transcript it belonged to.
@cstns cstns self-assigned this Sep 22, 2026
@cstns
cstns requested a review from andypalmi September 22, 2026 15:19
@cstns
cstns marked this pull request as ready for review September 22, 2026 15:19
@codecov

codecov Bot commented Sep 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.25%. Comparing base (06ba103) to head (ac831e6).

Additional details and impacted files
@@                        Coverage Diff                        @@
##           8630-expert-mqtt-reconnect-churn    #8632   +/-   ##
=================================================================
  Coverage                             77.25%   77.25%           
=================================================================
  Files                                   466      466           
  Lines                                 25131    25131           
  Branches                               6690     6690           
=================================================================
  Hits                                  19414    19414           
  Misses                                 5717     5717           
Flag Coverage Δ
backend 77.25% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Base automatically changed from 8630-expert-mqtt-reconnect-churn to main September 23, 2026 10:50
@cstns
cstns merged commit f8a701f into main Sep 23, 2026
27 checks passed
@cstns
cstns deleted the 8630-expert-disconnect-notice-delay branch September 23, 2026 10:50

This branch was successfully deployed

1 active deployment
staging ac831e6a Deployed Sep 23, 2026 by cstns via Remove application #11879
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expert chat reconnects in a hot loop and narrates every drop to the user

2 participants