Javascript 等待子进程完成,然后再真正停止
在我正在编码的模块中,我有一个开-关序列,这意味着要杀死一大群工人(32+)。问题是,父进程只是割断了,让孩子们自己处理。他们确实是通过自己的例行程序退出的,但家长不可能等待孩子们完成!(这是一个坏爸爸。) 我一直在尝试异步和其他东西的一切,但没有一个能真正坚持下去。我甚至尝试了一些解决方案,比如基于光纤的Javascript 等待子进程完成,然后再真正停止,javascript,node.js,process,Javascript,Node.js,Process,在我正在编码的模块中,我有一个开-关序列,这意味着要杀死一大群工人(32+)。问题是,父进程只是割断了,让孩子们自己处理。他们确实是通过自己的例行程序退出的,但家长不可能等待孩子们完成!(这是一个坏爸爸。) 我一直在尝试异步和其他东西的一切,但没有一个能真正坚持下去。我甚至尝试了一些解决方案,比如基于光纤的deasync,但它根本不起任何作用 Processs对象看起来是这样的: { "Worker group": { config: {/*...*/},
deasync
,但它根本不起任何作用
Processs对象看起来是这样的:
{
"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));
如您所见,我将步骤
方法指定为侦听器…但这并没有改变任何事情。我如何确保在进程真正脱机时调用步骤
,而不会在没有进一步警告的情况下使节点打嗝到最后?谢谢
编辑
事实上,我设法找到了一个解决办法,但这并不完全是我所寻找的。它确实起作用,但看看代码,你可能会明白为什么我称之为“黑客”
此外,我应该提到,当父进程退出时,我将返回到shell,突然,来自其他eiting子进程的消息出现在与当前shell相同的行上,即,好像我已经输入了这些内容。如果需要的话,我可以截屏,但我相信这很容易想象。从我收集的信息()当父母去世时,孩子们也应该这样做
在孩子们的学习过程中,有没有什么东西会让他们忽略这个词?一个活动的DB连接,等等。我会尝试在您的子进程中显式捕获SIGTERM,并在处理程序中执行任何必要的清理。至少这会让孩子们离父母离开的时间更近我实际上正在捕捉
SIGTERM
。主要的问题是,实际上,我得到了很多被屠宰的产出。比如,一旦我在应用程序中按下Ctrl+C(SIGINT
),应用程序就会执行预期的关闭例程。但在进程中间,主进程中断并将我返回到shell,而突然之间,退出子进程的很少输出被丢弃到我的shell中。使用ps-ef | grep$appName表明它们都消失了。我希望部分避免被破坏的输出,并确保在主程序退出之前所有内容都处于脱机状态。关于这个问题有什么想法吗?@IngwiePhoenix你能用输出编辑你原来的问题吗?答案将取决于它是stacktrace还是messages@frankprinto这只是信息——没有任何错误。事实上,我确实找到了一个解决方案——但这是一个非常艰难的过程,不能单独处理child_进程和集群事件。任何输出都不容易想象。。。下次请包括这些信息,即使只是针对您的程序的输出-谢谢!
// 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));