Fix idle-timer race and add sidecar exit diagnostics#458
Merged
Conversation
When the opencode serve sidecar process dies during a turn (crash, OOM, or idle-shutdown race), onceIdle previously held a dangling promise for the full 10-minute turnTimeoutMs. This caused freshopencode tabs to hang indefinitely — the client stayed 'running' and queued all subsequent messages. Now forgetSessionsForCwd emits a 'lost' event on each session emitter before deleting it. onceIdle listens for 'lost' and rejects immediately with OpencodeServeLostError. The adapter's materializeOrSend catch block already emits idle status and re-throws, so the client receives both the idle status (unblocking the UI) and the error message.
Fix idle-timer race (kata njfz): the idle-shutdown timer deleted the runningByCwd entry before killing the sidecar, so the close handler's guard failed and forgetSessionsForCwd was never called — leaking session emitters and leaving pending onceIdle promises hanging. Now calls forgetSessionsForCwd before deletion, emitting 'lost' events so onceIdle rejects promptly. Add sidecar exit diagnostics (kata 0ryp): - Log signal (not just code) in close handler to distinguish SIGTERM/ SIGKILL/SIGSEGV - Log a distinctive info message before idle-timer kill - Capture sidecar stderr at debug level instead of draining silently Includes onceIdle 'lost' event fix from debug/freshopencode-new-hang (cherry-picked as base — this branch supersedes it).
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
Fixes two issues discovered during investigation of the freshopencode
/newhang:Idle-timer race (kata njfz)
The idle-shutdown timer deleted the
runningByCwdentry before killing the sidecar process. When the child exited and the close handler fired, its guard (runningByCwd.get(cwdKey)) returned undefined, soforgetSessionsForCwdwas never called. This leaked session emitters and left pendingonceIdlepromises hanging for the full 10-minute timeout.Fix: Call
forgetSessionsForCwdbefore deleting therunningByCwdentry in the idle timer callback. This emits'lost'events on session emitters, causing pendingonceIdlepromises to reject promptly withOpencodeServeLostError.Sidecar exit diagnostics (kata 0ryp)
Every sidecar exit across 15+ log entries showed
code: null(killed by signal), but the close handler only loggedcode, notsignal, making it impossible to distinguish SIGTERM (idle timer/external), SIGKILL (OOM), or SIGSEGV (crash).Fixes:
signalalongsidecodein the close handlerinfomessage before idle-timer kill (distinguishes idle-timer kills from crash kills)debuglevel instead of silently draining (captures Go panic/segfault output)onceIdle 'lost' event fix
Includes the onceIdle
'lost'event fix fromdebug/freshopencode-new-hang(cherry-picked as base). This branch supersedes that branch.Test plan