Network Type Transition Optimization

Nucleic-Session: 40F8C53A-F001-423A-8607-EAE181DBE14B
Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
2026-07-04 23:39:36 -07:00
co-authored by Nucleic
parent ce4028ffc8
commit b0b041f268
@@ -483,6 +483,27 @@ final class HostConnection {
Task { await client.send(msg) } Task { await client.send(msg) }
} }
/// The device's network path changed (Wi-Fi ⇄ cellular, joined/left a network). React now rather
/// than waiting for a zombie LAN socket to time out or the reconnect backoff to elapse — this is
/// what makes the transport switch feel immediate. Only reconnect-managed hosts (a pinned host)
/// re-plan here; a host mid-pairing runs its own one-shot candidate chain.
func networkPathChanged() {
guard let host = pinnedHost else { return }
// Using (or dialing) LAN but LAN is no longer reachable → the socket is dead in all but name.
// Drop it and re-plan now; `buildCandidates` skips LAN and dials tailnet/relay.
if activeTransport == .lan, !pathMonitor.canUseLAN {
reconnectAttempts = 0
reconnect(to: host)
return
}
// Offline/reconnecting and the network just came back or changed → retry immediately instead
// of sitting out the remaining backoff.
if !connectivity.isLive, pathMonitor.isSatisfied {
reconnectAttempts = 0
reconnect(to: host)
}
}
private func scheduleRetry(host: PairedHost?) { private func scheduleRetry(host: PairedHost?) {
guard let host else { return } guard let host else { return }
reconnectAttempts += 1 reconnectAttempts += 1