fix(skill-mcp-manager): remove process listeners on disconnect and guard connection races
H7: Process 'exit'/'SIGINT' listeners registered per-session were never removed when all sessions disconnected, accumulating handlers. - Add unregisterProcessCleanup() called in disconnectAll() H8: Race condition where disconnectSession() during pending connection left orphan clients in state.clients. - Add disconnectedSessions Set to track mid-flight disconnects - Check disconnect marker after connection resolves, close if stale - Clear marker on reconnection for same session Tests: 6 pass (3 disconnect + 3 race)
This commit is contained in:
@@ -14,6 +14,7 @@ export async function getOrCreateClient(params: {
|
||||
config: ClaudeCodeMcpServer
|
||||
}): Promise<Client> {
|
||||
const { state, clientKey, info, config } = params
|
||||
state.disconnectedSessions.delete(info.sessionID)
|
||||
|
||||
const existing = state.clients.get(clientKey)
|
||||
if (existing) {
|
||||
@@ -28,14 +29,26 @@ export async function getOrCreateClient(params: {
|
||||
}
|
||||
|
||||
const expandedConfig = expandEnvVarsInObject(config)
|
||||
const connectionPromise = createClient({ state, clientKey, info, config: expandedConfig })
|
||||
const connectionPromise = (async () => {
|
||||
const client = await createClient({ state, clientKey, info, config: expandedConfig })
|
||||
|
||||
if (state.disconnectedSessions.has(info.sessionID)) {
|
||||
await forceReconnect(state, clientKey)
|
||||
throw new Error(`Session "${info.sessionID}" disconnected during MCP connection setup.`)
|
||||
}
|
||||
|
||||
return client
|
||||
})()
|
||||
|
||||
state.pendingConnections.set(clientKey, connectionPromise)
|
||||
|
||||
try {
|
||||
const client = await connectionPromise
|
||||
return client
|
||||
} finally {
|
||||
state.pendingConnections.delete(clientKey)
|
||||
if (state.pendingConnections.get(clientKey) === connectionPromise) {
|
||||
state.pendingConnections.delete(clientKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user