feat(tree): close rust family shell cutover

This commit is contained in:
lix-2026
2026-04-28 16:30:51 +08:00
parent 4ab36a9386
commit 7965c6c107
75 changed files with 9721 additions and 1174 deletions
+56 -5
View File
@@ -196,6 +196,32 @@ function getProcessNameByPid(pid) {
}
}
function terminatePid(pid) {
if (process.platform === "win32") {
execSync(`taskkill /PID ${pid} /T /F`, { stdio: "ignore" });
return;
}
try {
process.kill(pid, "SIGTERM");
} catch {
return;
}
}
function forceKillPid(pid) {
if (process.platform === "win32") {
execSync(`taskkill /PID ${pid} /T /F`, { stdio: "ignore" });
return;
}
try {
process.kill(pid, "SIGKILL");
} catch {
// 进程可能已经退出。
}
}
async function ensurePortFree(port, nameForLog) {
const free = await isPortFree("127.0.0.1", port);
if (free) return true;
@@ -225,7 +251,7 @@ async function ensurePortFree(port, nameForLog) {
logPrefix(nameForLog, `检测到端口 ${port} 被占用,准备重启(结束旧进程):${killPids.join(", ")}`);
for (const pid of killPids) {
try {
execSync(`taskkill /PID ${pid} /T /F`, { stdio: "ignore" });
terminatePid(pid);
} catch {
// ignore
}
@@ -240,6 +266,20 @@ async function ensurePortFree(port, nameForLog) {
await new Promise((r) => setTimeout(r, 150));
}
if (process.platform !== "win32") {
for (const pid of killPids) {
forceKillPid(pid);
}
for (let i = 0; i < 10; i += 1) {
// eslint-disable-next-line no-await-in-loop
const ok = await isPortFree("127.0.0.1", port, 250);
if (ok) return true;
// eslint-disable-next-line no-await-in-loop
await new Promise((r) => setTimeout(r, 150));
}
}
logPrefix(nameForLog, `端口 ${port} 仍未释放,可能有其他程序占用。`);
return false;
}
@@ -457,7 +497,18 @@ async function main() {
}
}
main().catch((error) => {
logPrefix("system", `启动失败:${error.message}`);
process.exit(1);
});
if (require.main === module) {
main().catch((error) => {
logPrefix("system", `启动失败:${error.message}`);
process.exit(1);
});
}
module.exports = {
ensurePortFree,
getListeningPidsByPort,
getProcessNameByPid,
isPortFree,
resolveBackendExecutable,
terminatePid,
};