Agents tunnels: auto-reconnect with backoff and wake-triggered retry#310868
Merged
Agents tunnels: auto-reconnect with backoff and wake-triggered retry#310868
Conversation
Tunnel-backed remote agent hosts previously had no auto-reconnect behavior — on laptop sleep / network drop the tunnel would flip to Disconnected and stay there until the user manually retried. This adds a reconnect loop inside TunnelAgentHostContribution: - Detect Connected→Disconnected transitions for still-cached tunnels and schedule an immediate reconnect. Only fires when the entry is explicitly Disconnected — if the entry has been removed (e.g. user clicked "Remove Remote"), we honour the removal and do not reconnect. - Exponential backoff on consecutive failures: 1s → 30s cap, up to 10 attempts, then pause. - Wake-triggered retry: on browser `online` or tab `visibilitychange` → visible, resume any paused reconnects. Rate-limited to one resume per 10s so rapid tab toggling can't hammer a permanently broken endpoint with unbounded attempt bursts. - Prune all reconnect state when a tunnel is uncached or the contribution is disposed.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds auto-reconnect behavior for tunnel-backed remote agent hosts in the Agents window (vs/sessions), improving resilience to sleep/network drops by retrying tunnel connections with exponential backoff and web wake triggers.
Changes:
- Detects Connected → Disconnected transitions for cached tunnel addresses and schedules reconnect attempts.
- Implements exponential backoff with a max delay cap and a pause after a fixed number of failures.
- Adds web-only wake-triggered resume (
online,visibilitychange) plus reconnect-state pruning/cleanup.
Show a summary per file
| File | Description |
|---|---|
src/vs/sessions/contrib/remoteAgentHost/browser/tunnelAgentHost.contribution.ts |
Adds reconnect state machine (tracking statuses, timers, attempts, pause/resume) and web wake listeners to automatically re-establish tunnel connections. |
Copilot's findings
Comments suppressed due to low confidence (1)
src/vs/sessions/contrib/remoteAgentHost/browser/tunnelAgentHost.contribution.ts:460
_pruneReconnectStateclears timeouts/attempts/pause flags for uncached tunnels, but_previousStatusesis only pruned from_handleConnectionChanges(which doesn’t run on tunnel-cache changes). If a tunnel is uncached and later re-cached without a connection-change event, the stale previous status can cause a spurious Connected→Disconnected transition and immediate reconnect scheduling. Consider also pruning_previousStatusesfor uncached addresses as part of_pruneReconnectState.
/** Drop reconnect state for addresses whose tunnel is no longer cached. */
private _pruneReconnectState(): void {
const cachedAddresses = new Set(
this._tunnelService.getCachedTunnels().map(t => `${TUNNEL_ADDRESS_PREFIX}${t.tunnelId}`)
);
for (const address of [...this._reconnectTimeouts.keys()]) {
if (!cachedAddresses.has(address)) {
this._cancelReconnect(address);
}
}
for (const address of [...this._reconnectAttempts.keys()]) {
if (!cachedAddresses.has(address)) {
this._reconnectAttempts.delete(address);
}
}
for (const address of [...this._reconnectPaused]) {
if (!cachedAddresses.has(address)) {
this._reconnectPaused.delete(address);
}
}
- Files reviewed: 1/1 changed files
- Comments generated: 2
Co-authored-by: Copilot <copilot@github.com>
Contributor
Screenshot ChangesBase: Changed (42)Added (18) |
Yoyokrazy
approved these changes
Apr 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Tunnel-backed remote agent hosts previously had no auto-reconnect behavior — on laptop sleep or network drop the tunnel would flip to
Disconnectedand stay there until the user manually retried. This adds a reconnect loop insideTunnelAgentHostContribution.Changes
In src/vs/sessions/contrib/remoteAgentHost/browser/tunnelAgentHost.contribution.ts:
Disconnected— if the entry has been removed from the connection list (e.g. user clicked "Remove Remote"), we honour the removal and do not reconnect.onlineor tabvisibilitychange→ visible, resume any paused reconnects. Rate-limited to one resume per 10s so rapid tab toggling can't hammer a permanently broken endpoint with unbounded attempt bursts. Only clears the attempt counter when the address is actually paused, so in-progress backoff sequences aren't short-circuited.setTimeouts cleared)._connectTunnelnow resets backoff/pause state on success and re-schedules on failure via_scheduleReconnect.Related
Pairs with the
microsoft/vscode-devPR that addsoffline+ long-hidden-resume force-close to the browser tunnel WebSocket.Risk
TunnelAgentHostContribution— does not touch the genericIRemoteAgentHostServicereconnect machinery (which still explicitly skips tunnel entries inreconnect()).isWeb-gated._updateConnectionStatusespath — no new UI surface.Follow-ups (not in this PR)