fix: add disposed guard to MCP manager and guard unregister on pending connections
This commit is contained in:
@@ -81,7 +81,7 @@ async function cleanupIdleClients(state: SkillMcpManagerState): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.clients.size === 0) {
|
if (state.clients.size === 0 && state.pendingConnections.size === 0) {
|
||||||
stopCleanupTimer(state)
|
stopCleanupTimer(state)
|
||||||
unregisterProcessCleanup(state)
|
unregisterProcessCleanup(state)
|
||||||
}
|
}
|
||||||
@@ -119,7 +119,7 @@ export async function disconnectSession(state: SkillMcpManagerState, sessionID:
|
|||||||
state.pendingConnections.delete(key)
|
state.pendingConnections.delete(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.clients.size === 0) {
|
if (state.clients.size === 0 && state.pendingConnections.size === 0) {
|
||||||
stopCleanupTimer(state)
|
stopCleanupTimer(state)
|
||||||
unregisterProcessCleanup(state)
|
unregisterProcessCleanup(state)
|
||||||
}
|
}
|
||||||
@@ -127,6 +127,7 @@ export async function disconnectSession(state: SkillMcpManagerState, sessionID:
|
|||||||
|
|
||||||
export async function disconnectAll(state: SkillMcpManagerState): Promise<void> {
|
export async function disconnectAll(state: SkillMcpManagerState): Promise<void> {
|
||||||
state.shutdownGeneration++
|
state.shutdownGeneration++
|
||||||
|
state.disposed = true
|
||||||
stopCleanupTimer(state)
|
stopCleanupTimer(state)
|
||||||
unregisterProcessCleanup(state)
|
unregisterProcessCleanup(state)
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ function createState(): SkillMcpManagerState {
|
|||||||
idleTimeoutMs: 5 * 60 * 1000,
|
idleTimeoutMs: 5 * 60 * 1000,
|
||||||
shutdownGeneration: 0,
|
shutdownGeneration: 0,
|
||||||
inFlightConnections: new Map(),
|
inFlightConnections: new Map(),
|
||||||
|
disposed: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
trackedStates.push(state)
|
trackedStates.push(state)
|
||||||
|
|||||||
@@ -15,6 +15,10 @@ export async function getOrCreateClient(params: {
|
|||||||
}): Promise<Client> {
|
}): Promise<Client> {
|
||||||
const { state, clientKey, info, config } = params
|
const { state, clientKey, info, config } = params
|
||||||
|
|
||||||
|
if (state.disposed) {
|
||||||
|
throw new Error(`MCP manager for "${info.sessionID}" has been shut down, cannot create new connections.`)
|
||||||
|
}
|
||||||
|
|
||||||
const existing = state.clients.get(clientKey)
|
const existing = state.clients.get(clientKey)
|
||||||
if (existing) {
|
if (existing) {
|
||||||
existing.lastUsedAt = Date.now()
|
existing.lastUsedAt = Date.now()
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ function createState(): SkillMcpManagerState {
|
|||||||
idleTimeoutMs: 5 * 60 * 1000,
|
idleTimeoutMs: 5 * 60 * 1000,
|
||||||
shutdownGeneration: 0,
|
shutdownGeneration: 0,
|
||||||
inFlightConnections: new Map(),
|
inFlightConnections: new Map(),
|
||||||
|
disposed: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
trackedStates.push(state)
|
trackedStates.push(state)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export class SkillMcpManager {
|
|||||||
idleTimeoutMs: 5 * 60 * 1000,
|
idleTimeoutMs: 5 * 60 * 1000,
|
||||||
shutdownGeneration: 0,
|
shutdownGeneration: 0,
|
||||||
inFlightConnections: new Map(),
|
inFlightConnections: new Map(),
|
||||||
|
disposed: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
private getClientKey(info: SkillMcpClientInfo): string {
|
private getClientKey(info: SkillMcpClientInfo): string {
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ export interface SkillMcpManagerState {
|
|||||||
idleTimeoutMs: number
|
idleTimeoutMs: number
|
||||||
shutdownGeneration: number
|
shutdownGeneration: number
|
||||||
inFlightConnections: Map<string, number>
|
inFlightConnections: Map<string, number>
|
||||||
|
disposed: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SkillMcpClientConnectionParams {
|
export interface SkillMcpClientConnectionParams {
|
||||||
|
|||||||
Reference in New Issue
Block a user