MCPcopy
hub / github.com/codeaashu/claude-code / doReconnect

Function doReconnect

src/bridge/replBridge.ts:617–836  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

615 }
616
617 async function doReconnect(): Promise<boolean> {
618 environmentRecreations++
619 // Invalidate any in-flight v2 handshake — the environment is being
620 // recreated, so a stale transport arriving post-reconnect would be
621 // pointed at a dead session.
622 v2Generation++
623 logForDebugging(
624 `[bridge:repl] Reconnecting after env lost (attempt ${environmentRecreations}/${MAX_ENVIRONMENT_RECREATIONS})`,
625 )
626
627 if (environmentRecreations > MAX_ENVIRONMENT_RECREATIONS) {
628 logForDebugging(
629 `[bridge:repl] Environment reconnect limit reached (${MAX_ENVIRONMENT_RECREATIONS}), giving up`,
630 )
631 return false
632 }
633
634 // Close the stale transport. Capture seq BEFORE close — if Strategy 1
635 // (tryReconnectInPlace) succeeds we keep the SAME session, and the
636 // next transport must resume where this one left off, not replay from
637 // the last transport-swap checkpoint.
638 if (transport) {
639 const seq = transport.getLastSequenceNum()
640 if (seq > lastTransportSequenceNum) {
641 lastTransportSequenceNum = seq
642 }
643 transport.close()
644 transport = null
645 }
646 // Transport is gone — wake the poll loop out of its at-capacity
647 // heartbeat sleep so it can fast-poll for re-dispatched work.
648 wakePollLoop()
649 // Reset flush gate so writeMessages() hits the !transport guard
650 // instead of silently queuing into a dead buffer.
651 flushGate.drop()
652
653 // Release the current work item (force=false — we may want the session
654 // back). Best-effort: the env is probably gone, so this likely 404s.
655 if (currentWorkId) {
656 const workIdBeingCleared = currentWorkId
657 await api
658 .stopWork(environmentId, workIdBeingCleared, false)
659 .catch(() => {})
660 // When doReconnect runs concurrently with the poll loop (ws_closed
661 // handler case — void-called, unlike the awaited onEnvironmentLost
662 // path), onWorkReceived can fire during the stopWork await and set
663 // a fresh currentWorkId. If it did, the poll loop has already
664 // recovered on its own — defer to it rather than proceeding to
665 // archiveSession, which would destroy the session its new
666 // transport is connected to.
667 if (currentWorkId !== workIdBeingCleared) {
668 logForDebugging(
669 '[bridge:repl] Poll loop recovered during stopWork await — deferring to it',
670 )
671 environmentRecreations = 0
672 return true
673 }
674 currentWorkId = null

Callers 1

Calls 12

logForDebuggingFunction · 0.85
tryReconnectInPlaceFunction · 0.85
logEventFunction · 0.85
updateSessionBridgeIdFunction · 0.85
toCompatSessionIdFunction · 0.85
writeBridgePointerFunction · 0.85
getLastSequenceNumMethod · 0.80
dropMethod · 0.80
archiveSessionFunction · 0.70
errorMessageFunction · 0.50
closeMethod · 0.45
clearMethod · 0.45

Tested by

no test coverage detected