修复AI游戏创作跨平台运行竞态
保存独立进程组标识并在启动失败或退出时清理后代进程 兼容macOS下带前置选项的npm脚本命令校验 修复进程会话输出上限投影、测试夹具与锁污染问题 收敛Agent运行时lane释放、并发锁初始化与异步审计时序竞态 补充Node与Native Shell回归测试并同步排障文档
This commit is contained in:
@@ -187,7 +187,13 @@ function spawnChild(command, args, options, spawnImpl = spawn) {
|
||||
detached: !useShell,
|
||||
stdio: 'inherit',
|
||||
});
|
||||
const lifecycle = { failure: null, promise: null };
|
||||
const lifecycle = {
|
||||
failure: null,
|
||||
promise: null,
|
||||
// detached 子进程在 POSIX 下以自身 PID 作为 PGID。leader 退出后
|
||||
// child.pid 仍是清理其后代的唯一稳定句柄,必须随生命周期保留。
|
||||
processGroupId: !useShell && Number.isInteger(child.pid) ? child.pid : null,
|
||||
};
|
||||
lifecycle.promise = new Promise((resolveLifecycle) => {
|
||||
child.once('error', (error) => {
|
||||
lifecycle.failure = { type: 'error', error };
|
||||
@@ -231,21 +237,36 @@ function formatChildFailure(failure) {
|
||||
}
|
||||
|
||||
function stopChild(child, signal = 'SIGTERM') {
|
||||
if (!child || child.exitCode != null || child.signalCode != null) {
|
||||
if (!child) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (process.platform !== 'win32') {
|
||||
const processGroupId = childLifecycles.get(child)?.processGroupId;
|
||||
if (Number.isInteger(processGroupId)) {
|
||||
try {
|
||||
process.kill(-processGroupId, signal);
|
||||
return;
|
||||
} catch (error) {
|
||||
if (error?.code === 'ESRCH') {
|
||||
return;
|
||||
}
|
||||
// leader 尚存活时保留 direct child fallback;leader 已退出则仍以
|
||||
// 负 PGID kill 的失败为准,不能误以为 descendants 已清理。
|
||||
if (child.exitCode != null || child.signalCode != null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (child.exitCode != null || child.signalCode != null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (process.platform !== 'win32' && Number.isInteger(child.pid)) {
|
||||
process.kill(-child.pid, signal);
|
||||
} else {
|
||||
child.kill(signal);
|
||||
}
|
||||
child.kill(signal);
|
||||
} catch {
|
||||
try {
|
||||
child.kill(signal);
|
||||
} catch {
|
||||
// ignore cleanup races
|
||||
}
|
||||
// ignore cleanup races
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user