microsoft / microsoft/vscode-remote-release
Provide a way to reset Remote-SSH connection state without reloading the window
Nobody has claimed this yet.
- Dominant language
- Dockerfile
- Stars
- 4.2k
- Forks
- 469
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 1
Description
Problem
microsoft/vscode#310131 (landed in 1.120) added _keepAliveTimeoutCheck to PersistentProtocol (src/vs/base/parts/ipc/common/ipc.net.ts). That fix triggers _onSocketTimeout after 20s of no inbound data on an idle connection, which in turn calls PersistentConnection._beginReconnecting() in src/vs/platform/remote/common/remoteAgentConnection.ts. _beginReconnecting() re-runs resolveAuthority and re-establishes the connection.
The recovery path reuses cached reconnection tokens, and that's where the next failure mode lives. When the remote server's PID has already changed by the time _beginReconnecting() runs, the server has no record of the cached tokens. It rejects the reconnection with Connection error: Unknown reconnection token (never seen). PersistentConnection classifies that as permanent and stops retrying. The user sees Reload Window.
Three trigger classes guarantee the PID change before detection can fire:
- Mac sleeps for more than ~5 minutes. The remote VS Code server's
--enable-remote-auto-shutdowntimer expires while the client is suspended. On wake,_keepAliveTimeoutCheckcorrectly notices the dead connection, but the cached tokens are already stale because a fresh server has been started by Remote-SSH's setup script. - Workspace or dev-container restart. Server PID changes instantly. The cached tokens point at the dead PID before any keepalive interval could expire.
- Pod or container restart at the platform layer (Kubernetes rollover, container-runtime crash, and so on). Same outcome.
In all three cases, _beginReconnecting() runs as designed and still fails. The only working recovery is workbench.action.reloadWindow, which destroys everything not on disk: unsaved buffers, terminal sessions and scrollback, debug sessions, panel layout, output channels, search results.
Evidence
A 3-day proxy-log sample from one Remote-SSH user (Coder-backed remote authority) shows 8 distinct permanent-failure cascades, each ending in Reload Window. Code-level projection: post-1.120 detection (_keepAliveTimeoutCheck) catches roughly half, the short tunnel stalls where the remote server is still alive when detection fires. The other half hit the three trigger classes above and cannot be caught by any detection improvement, because the server PID is already gone before keepalives could possibly notice. A post-1.120 bundle from the same user is planned and will be added as a follow-up; the architectural argument doesn't depend on it, because no detection logic can produce tokens the server never issued.
Ask
A command, plausibly workbench.action.remote.resetConnection, that an extension can invoke via vscode.commands.executeCommand. Behavior:
- Disposes the current
ManagementandExtensionHostPersistentConnections cleanly (no token reuse on the next attempt). - Clears the reconnection-token cache for the target authority.
- Re-runs
resolveAuthorityfrom scratch. - Re-establishes
ManagementandExtensionHost, preserving in-window state (editor buffers and dirty markers, terminal sessions and scrollback, debug sessions, panel layout, output channels) to whatever extent the protocol permits.
The mechanism for steps 3-4 already exists for the detection-driven path: _keepAliveTimeoutCheck -> _onSocketTimeout -> PersistentConnection._beginReconnecting(). The ask is to expose a sibling entry point that also invalidates the cached connection token before re-running resolveAuthority, callable from extension space.
Optional argument: the target authority string (defaults to the current remote authority).
Resolver and remote-authority extensions would call this when they observe permanent-failure markers in the Remote-SSH log: Connection error: Unknown reconnection token, permanent error ... will give up now, socketFactory.connect() failed or timed out, and so on. Even partial state preservation (editors and terminals survive; debug sessions don't) would substantially exceed the current Reload Window outcome.
Why now
Extensions today have two options and both lose state:
- Tell users to Reload Window. What the current permanent-error dialog already does. Loses all in-window state.
- Kill the SSH proxy process. A fresh
resolveAuthorityruns but cached tokens persist in_PersistentProtocol, so the reconnection hits the sameUnknown reconnection tokenrejection. Doesn't work.
The token cache is private to _PersistentProtocol and has no vscode API surface. There is no third option available from extension space, so resolver authors can't paper over this themselves. Filing this as a direct follow-up to the detection landing in 1.120: detection without recovery still loses user state, and detection is now in.
Related
- microsoft/vscode#310131: keepalive timeout detection (landed 1.120). Addresses the detection half of this problem.
- #11538: stale
data.jsonshort-circuit also forces Reload Window. Same window-reload tax on the user.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading src/vs/base/parts/ipc/common/ipc.net.ts and src/vs/platform/remote/common/remoteAgentConnection.ts, then trace the existing _keepAliveTimeoutCheck recovery path. Identify the connection and token-cache entry points needed for an extension-invocable reset. Done means a command can invalidate tokens, rerun resolveAuthority, and restore remote connections while preserving in-window state as far as the protocol permits.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, kubernetes, typescript
- Domain
- api, developer-experience, infrastructure
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100