在我编码的模块中,我有一个关闭序列,意在杀死一大堆工人(32+)。问题是,父进程只是切断并让孩子独立。他们确实通过他们自己的惯例退出,但父母没有办法等待孩子们完成! (Dat bad daddy doe。)
我一直在尝试使用Async和其他东西,但没有人真的会坚持下去。我甚至尝试过基于光纤的deasync
等解决方案 - 但它根本不做任何事情。
Processes对象如下所示:
{
"Worker group": {
config: {/*...*/},
children: [
{ /* child_process.spawn or cluster.Worker instance */ }
]
}
}
所以我要做的是迭代每组工人和SIGTERM
他们。但无论如何,父母都会退出并独自离开孩子。这是我的代码:
// Shutdown handlers
var _shut = false;
this.addShutdownHandler(function(ctx, next){
if(_shut) return;
_shut = true;
for(var id in this.procs) {
var p = this.procs[id];
async.forEachOf(p.children, function(c, n, step){
c.on("exit",step).kill();
}, next);
}
}.bind(this));
正如您所看到的,我将step
方法指定为侦听器......但这并没有改变任何内容。如何确保在进程真正脱机时调用step
并且在没有进一步警告的情况下没有使节点打嗝到最后?谢谢!
我实际上设法找到了解决方案,但这并不完全是我所寻求的。它完成了这项工作,但是查看代码,您可能会理解为什么我称之为“hacky”。
// Shutdown handlers
var _shut = false;
this.addShutdownHandler(function(ctx, next){
if(_shut) return;
_shut = true;
// Merge all the children together.
var allChildren = [];
for(var id in this.procs) {
var p = this.procs[id];
p.children.forEach(function(c){
// Trigger shutdown and add to list.
c.on("exit", function(){
c._exited = true;
c._exitArgs = arguments;
}).kill(PowerHouse.KILL_SIGNAL);
allChildren.push(c);
});
}
// Make sure they all are gone.
var allDone = false;
async.whilst(
function() {
return !allDone;
},
function(proceed) {
var allTrue = [];
var newChildren = [];
allChildren.forEach(function(c, i, ref){
if(!c._exited) {
if(c.pid) {
try {
process.kill(c.pid, 0);
} catch (e) {
c._exited = true;
}
} else if(c.process && c.process.pid) {
try {
process.kill(c.process.pid, 0);
} catch (e) {
c._exited = true;
}
} else if(c.isDead) {
c._exited = c.isDead();
}
}
// Overwriting the other array
if(!c._exited) {
newChildren.push(c);
}
allTrue.push(c._exited);
});
if(allTrue.length > 0) {
for(var i in allTrue) {
if(!allTrue[i]) {
allDone = false;
break;
}
}
} else {
// There are NO entries. It's safe to say...
allDone = true;
}
allChildren = newChildren;
// async.nextTick does NOT do this...? I am really surprised.
// FIXME: ...an answer.
async.setImmediate(proceed);
},
function(err) {
next(err);
}
);
}.bind(this));
更进一步,我应该提一下,当父母退出时,我会回到我的shell,突然,来自其他正在进行的子进程的消息出现在与当前shell相同的行上 - 就好像我输入了那些东西如果想要我可以截图,但我相信它很容易想象。
答案 0 :(得分:0)
从我收集的内容(How to prevent child node processes from getting killed with the parent node process?)当父母去世时,孩子们也应该这样做。
子进程中是否有某些东西会让他们忽略SIGTERM?一个活动的数据库连接等我会尝试在你的子进程中显式捕获SIGTERM并在处理程序中进行必要的清理。至少这会使孩子们离父母离开时更接近