Skip to content

hub: keep reconnecting trusted devices that briefly leave mDNS#89

Closed
andig wants to merge 3 commits into
enbility:devfrom
andig:fix/trusted-reconnect-mdns-drop
Closed

hub: keep reconnecting trusted devices that briefly leave mDNS#89
andig wants to merge 3 commits into
enbility:devfrom
andig:fix/trusted-reconnect-mdns-drop

Conversation

@andig

@andig andig commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Fixes #88.

cleanupRemovedMdnsEntries cancels the pending connection dial (delay timer + attempt counter) for every SKI missing from the latest mDNS snapshot. That is the intended resource saving for untrusted discovery (introduced in 67a274b), but it also strands trusted/paired devices: when a trusted remote briefly stops announcing (e.g. during a restart) after the hub has already scheduled a dial, the next snapshot omits its SKI, the dial is cancelled, and the reconnect is not re-initiated until the device happens to re-announce.

Skip the cleanup for SKIs where IsRemoteServiceForSKIPaired is true, so a trusted device keeps retrying across a transient mDNS drop. Untrusted discovery attempts are still cleaned up as before.

Test

Added TestReportMdnsEntries_TrustedServiceSurvivesTransientMdnsDrop: a trusted service with a scheduled reconnect, then an mDNS report that omits its SKI; the pending dial must survive.

Without the fix (test applied to unchanged hub_mdns.go) it fails, showing the dial being cancelled:

--- FAIL: TestReportMdnsEntries_TrustedServiceSurvivesTransientMdnsDrop
    map[string]*hub.connectionDelayTimer{} does not contain "0123...ffff"
      pending reconnect timer for a trusted device must survive a transient mDNS drop
    map[string]int{} does not contain "0123...ffff"
      connection attempt counter for a trusted device must survive a transient mDNS drop

With the fix it passes, and the full hub package is green.

Context

Found via a flaky EEBus reconnect-after-restart in evcc (evcc-io/evcc#31534, evcc-io/evcc#31570), whose logs show the cancellation for a paired controlbox:

delaying connection to <ski> by 90ms to minimize double connection probability
hub: cleaning up connection attempts for SKI <ski> (no longer in mDNS)

This change removes that cause and substantially reduces the downstream flake, but does not fully eliminate it: a separate race, where a trusted device's re-announcement after restart is rejected as a replay and its trust is transiently not set when the cleanup runs, can still cancel the reconnect. That is out of scope here and worth tracking separately.

🤖 Generated with Claude Code

cleanupRemovedMdnsEntries cancels the connection delay timer and attempt
counter for any SKI missing from the latest mDNS snapshot. For an
untrusted device that genuinely left the network this is the intended
resource saving, but for a trusted/paired device it strands a pending
reconnect: the scheduled dial is cancelled and only re-initiated once the
device happens to re-announce.

This regularly happens right after the remote restarts - it stops
announcing for a moment while the local hub, having re-registered the
persisted trust via RegisterRemoteService, has already scheduled a dial.
A single missing snapshot then cancels that dial and the device stays
disconnected until the next announcement.

Skip the cleanup for trusted SKIs so their pending reconnect survives a
transient mDNS drop; untrusted discovery attempts are still cleaned up.
@coveralls

coveralls commented Jul 9, 2026

Copy link
Copy Markdown

Coverage Status

coverage: 93.008% (+0.04%) from 92.972% — andig:fix/trusted-reconnect-mdns-drop into enbility:dev

@andig

andig commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Test flake seems unrelated but I can't restart it.

@sthelen-enqs

Copy link
Copy Markdown
Contributor

I think we'll need to discuss in the team if and how we want to handle this.
As it is, this commit doesn't make sense, if we wanted to make sure that we keep trying to connect to the last known addresses for a ship node then it would make more sense to revert 67a274b completely instead.
With your patch the whole function just becomes essentially dead code because we won't have connection attempts to devices that we don't trust.
I'll close this for now and open up a discussion based on #88 in the team

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.

Trusted device not reconnected after a brief mDNS drop

3 participants