feat: auto-restart crashed language server with exponential backoff#163
Open
you922 wants to merge 2 commits intodwgx:masterfrom
Open
feat: auto-restart crashed language server with exponential backoff#163you922 wants to merge 2 commits intodwgx:masterfrom
you922 wants to merge 2 commits intodwgx:masterfrom
Conversation
added 2 commits
May 10, 2026 17:03
When a language server instance crashes, the proxy now automatically respawns it after a brief backoff instead of leaving downstream requests hanging with ECONNRESET / ERR_HTTP2_CONNECT errors. Implementation: - scheduleLsRestart() in langserver.js with configurable exponential backoff (base: 1s → 2s → 4s → 8s) - Per-key retry counter to prevent infinite loops on permanent errors - Env-configurable: LS_AUTO_RESTART, LS_AUTO_RESTART_MAX_RETRIES, LS_AUTO_RESTART_BASE_DELAY_MS - getRestartStats() for monitoring restart health - All timeouts use .unref() to not block process exit Configuration: LS_AUTO_RESTART=1 # default: on LS_AUTO_RESTART_MAX_RETRIES=3 # default: 3 LS_AUTO_RESTART_BASE_DELAY_MS=1000 # default: 1000ms Fixes: dwgx#157
Added _intentionalShutdown Set to track LS instances being shut down deliberately via stopLanguageServer() or restartLsForProxy(). Without this, the exit handler unconditionally fires scheduleLsRestart for every killed process, spawning unwanted LS instances. Changes: - _intentionalShutdown Set prevents restart for intentional kills - restartLsForProxy marks key before process.kill - stopLanguageServer marks all keys before kill loop - Exit handler checks Set before calling scheduleLsRestart - Cleanup after exit check (prevents set growth)
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
When a Windsurf language server instance crashes, the proxy now automatically respawns it after a brief backoff instead of leaving downstream requests hanging with
ECONNRESET/ERR_HTTP2_CONNECTerrors.Problem
The language server binary occasionally crashes due to memory pressure, upstream API changes, or transient errors. Currently, the proxy logs the crash and cleans up — but all subsequent requests to that LS instance get connection errors until a manual restart or the next
ensureLs()call from a new request.Reported in #157 where
LanguageServerfails to start and users are left with no working endpoint.Solution
New
scheduleLsRestart()function added tosrc/langserver.js:proc.on('exit')— intercepts the exit event and schedules a timed restart_restartAttemptsMap prevents duplicate restart timers.unref()timeouts: doesn't block Node.js process exitgetRestartStats(): exposes restart attempt counts for monitoringConfiguration
Set
LS_AUTO_RESTART=0to disable (restore previous behavior).Backward Compatibility
LS_AUTO_RESTART=1(enabled) — this changes behavior but improves reliabilityLS_AUTO_RESTART=0for the exact pre-PR behaviorCloses #157