mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2026-03-01 16:20:25 +00:00
Cleanup orphaned Electron child processes
Add cleanupOrphanedProcesses to terminate leftover child processes when running in Electron. The function imports Electron at runtime, uses app.getAppMetrics() to enumerate processes, excludes the main and provided worker PIDs, and sends SIGTERM to stray PIDs while ignoring already-dead processes and API errors. Also invoke this cleanup in restartWorker after starting the new worker to avoid lingering processes after restarts. Includes @ts-ignore for the dynamic Electron import and debug logging on failure.
This commit is contained in:
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -10,7 +10,7 @@ permissions: write-all
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
OPENROUTER_API_URL: https://91vip.futureppo.top/v1/chat/completions
|
OPENROUTER_API_URL: https://91vip.futureppo.top/v1/chat/completions
|
||||||
OPENROUTER_MODEL: "gemini-3-flash-preview"
|
OPENROUTER_MODEL: "glm-4.7"
|
||||||
RELEASE_NAME: "NapCat"
|
RELEASE_NAME: "NapCat"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|||||||
@@ -113,6 +113,42 @@ function forceKillProcess (pid: number): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理进程树中的残留子进程(Electron 模式专用)
|
||||||
|
* 排除当前主进程和新 worker 进程
|
||||||
|
*/
|
||||||
|
async function cleanupOrphanedProcesses (excludePids: number[]): Promise<void> {
|
||||||
|
if (!isElectron) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 使用 Electron 的 app.getAppMetrics() 获取所有相关进程
|
||||||
|
// @ts-ignore - electron 运行时存在但类型声明可能缺失
|
||||||
|
const electron = await import('electron');
|
||||||
|
if (electron.app && typeof electron.app.getAppMetrics === 'function') {
|
||||||
|
const metrics = electron.app.getAppMetrics();
|
||||||
|
const mainPid = process.pid;
|
||||||
|
|
||||||
|
for (const metric of metrics) {
|
||||||
|
const pid = metric.pid;
|
||||||
|
// 排除主进程、新 worker 进程和明确排除的 PID
|
||||||
|
if (pid === mainPid || excludePids.includes(pid)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 尝试终止残留进程
|
||||||
|
try {
|
||||||
|
process.kill(pid, 'SIGTERM');
|
||||||
|
logger.log(`[NapCat] [Process] 已清理残留进程: PID ${pid} (${metric.type})`);
|
||||||
|
} catch {
|
||||||
|
// 进程可能已经不存在,忽略错误
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Electron API 不可用或出错,静默忽略
|
||||||
|
logger.logDebug?.('[NapCat] [Process] 清理残留进程时出错:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重启 Worker 进程
|
* 重启 Worker 进程
|
||||||
*/
|
*/
|
||||||
@@ -166,6 +202,13 @@ export async function restartWorker (secretKey?: string, port?: number): Promise
|
|||||||
|
|
||||||
// 5. 启动新进程(重启模式不传递快速登录参数,传递密钥和端口)
|
// 5. 启动新进程(重启模式不传递快速登录参数,传递密钥和端口)
|
||||||
await startWorker(false, secretKey, port);
|
await startWorker(false, secretKey, port);
|
||||||
|
|
||||||
|
// 6. Electron 模式下清理可能残留的子进程
|
||||||
|
if (isElectron && currentWorker?.pid) {
|
||||||
|
const excludePids = [process.pid, currentWorker.pid];
|
||||||
|
await cleanupOrphanedProcesses(excludePids);
|
||||||
|
}
|
||||||
|
|
||||||
isRestarting = false;
|
isRestarting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user