mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-01-02 22:32:27 +08:00
fix(mcp-server): add graceful shutdown to prevent zombie processes (#477)
* fix(mcp-server): add graceful shutdown to prevent zombie processes Add lifecycle handlers to properly exit the MCP server when the parent application closes: - Listen for stdin close/end events (primary method for all platforms) - Handle SIGINT/SIGTERM signals - Handle stdout broken pipe errors - Export shutdown() function from http-server to clean up resources * chore(mcp-server): bump version to 0.1.11
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@next-ai-drawio/mcp-server",
|
"name": "@next-ai-drawio/mcp-server",
|
||||||
"version": "0.1.10",
|
"version": "0.1.11",
|
||||||
"description": "MCP server for Next AI Draw.io - AI-powered diagram generation with real-time browser preview",
|
"description": "MCP server for Next AI Draw.io - AI-powered diagram generation with real-time browser preview",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
|||||||
@@ -127,7 +127,12 @@ function cleanupExpiredSessions(): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setInterval(cleanupExpiredSessions, 5 * 60 * 1000)
|
const cleanupIntervalId = setInterval(cleanupExpiredSessions, 5 * 60 * 1000)
|
||||||
|
|
||||||
|
export function shutdown(): void {
|
||||||
|
clearInterval(cleanupIntervalId)
|
||||||
|
stopHttpServer()
|
||||||
|
}
|
||||||
|
|
||||||
export function getServerPort(): number {
|
export function getServerPort(): number {
|
||||||
return serverPort
|
return serverPort
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import {
|
|||||||
getState,
|
getState,
|
||||||
requestSync,
|
requestSync,
|
||||||
setState,
|
setState,
|
||||||
|
shutdown,
|
||||||
startHttpServer,
|
startHttpServer,
|
||||||
waitForSync,
|
waitForSync,
|
||||||
} from "./http-server.js"
|
} from "./http-server.js"
|
||||||
@@ -618,6 +619,31 @@ server.registerTool(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Graceful shutdown handler
|
||||||
|
let isShuttingDown = false
|
||||||
|
function gracefulShutdown(reason: string) {
|
||||||
|
if (isShuttingDown) return
|
||||||
|
isShuttingDown = true
|
||||||
|
log.info(`Shutting down: ${reason}`)
|
||||||
|
shutdown()
|
||||||
|
process.exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle stdin close (primary method - works on all platforms including Windows)
|
||||||
|
process.stdin.on("close", () => gracefulShutdown("stdin closed"))
|
||||||
|
process.stdin.on("end", () => gracefulShutdown("stdin ended"))
|
||||||
|
|
||||||
|
// Handle signals (may not work reliably on Windows)
|
||||||
|
process.on("SIGINT", () => gracefulShutdown("SIGINT"))
|
||||||
|
process.on("SIGTERM", () => gracefulShutdown("SIGTERM"))
|
||||||
|
|
||||||
|
// Handle broken pipe (writing to closed stdout)
|
||||||
|
process.stdout.on("error", (err) => {
|
||||||
|
if (err.code === "EPIPE" || err.code === "ERR_STREAM_DESTROYED") {
|
||||||
|
gracefulShutdown("stdout error")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// Start the MCP server
|
// Start the MCP server
|
||||||
async function main() {
|
async function main() {
|
||||||
log.info("Starting MCP server for Next AI Draw.io (embedded mode)...")
|
log.info("Starting MCP server for Next AI Draw.io (embedded mode)...")
|
||||||
|
|||||||
Reference in New Issue
Block a user