节点 Kue 和子进程 - 从生成的进程中获取错误
Posted
技术标签:
【中文标题】节点 Kue 和子进程 - 从生成的进程中获取错误【英文标题】:Node Kue and Child Process - get error from spawned process 【发布时间】:2014-08-17 00:25:30 【问题描述】:我尝试使用 Kue 通过作业队列生成一个执行 cpu 密集型计算的子进程。我目前的代码如下所示:
consumer.js
var kue = require('kue');
var util = require('util');
var spawn = require('child_process').spawn;
var jobs = kue.createQueue();
jobs.process('calc', 2, function(job, done)
var work = spawn('Rscript', ['opti2.R', job.data.file]);
work.stderr.on('data', function (data)
job.log('stderr: ' + data);
);
work.stdout.on('data', function (data)
job.log('stdout: ' + data);
);
work.on('exit', function (code, signal)
console.log('child process exited with code ' + code + ' with singal ' + signal);
if(code != 0)
done(****How to get the stderr of the child process as an error here***);
else
done(Error());
);
);
代码在某种程度上做了我想做的事,但是有没有更好的方法来报告作业失败(向 Kue)并从生成的进程中获取标准错误?
【问题讨论】:
您希望将孩子的stdio
传送到父母的stdio
,还是将其发送到Kue
?
@LeonidBeschastny:不确定(对节点/编程来说非常新),但希望将生成过程中的错误作为 Kue 中的错误/失败消息。你有什么推荐的?
【参考方案1】:
您可以使用job.log
method直接向Kue
发送数据。
我还建议您从.spawn
切换到.exec
,因为它在最终回调中返回stdout
和stderr
作为字符串以及一个很好的error
,这很适合您的需求:
var exec = require('child_process').exec;
jobs.process('calc', 2, function(job, done)
exec('Rscript opti2.R ' + job.data.file, function (error, stdout, stderr)
if (stdout.length > 0) job.log('stdout: ' + stdout);
if (stderr.length > 0) job.log('stderr: ' + stderr);
done(error);
);
);
虽然解决方案也适用于 .spawn
:只需将代码中的每个 console.log
调用替换为 job.log
。
不过,您可能希望缓冲您的 stderr
以便将其分成一个块发送给 Kue:
jobs.process('calc', 2, function(job, done)
var work = spawn('Rscript', ['opti2.R', job.data.file]);
var stderr = '';
work.stderr.on('data', function (data)
stderr += data;
);
work.stdout.on('data', function (data)
job.log(data); // sending arriving `stdout` chunks as normal log events
);
work.on('close', function (code, signal)
console.log('child process exited with code ' + code + ' with singal ' + signal);
if(code != 0)
done(stderr); // sending all collected stderr as an explanation
else
done();
);
);
我还建议使用close
事件而不是exit
,因为它等待孩子的stdio
流。
更多信息见Event: 'exit'
docs:
该事件在子进程结束后触发。
请注意,子进程 stdio 流可能仍处于打开状态。
和Event: 'close'
docs:
当子进程的 stdio 流有 全部终止。
【讨论】:
计算运行 30-90 分钟并输出(标准输出),我想返回网页,因此我使用 spawn。有没有办法将错误从 stderr 事件传递到 Kue 的 done() ? @JamesBund 正如我所说,此解决方案也适用于.spawn
,只需使用job.log
将数据发送到Kue
,而不是将其记录到控制台。
不确定是否误解了某些东西,但是使用 job.log 我仍然无法在孩子的退出事件中使用来自孩子的 stderr 作为 done() 的参数?已更新代码..
@JamesBund 在.on 'exit'
回调中获得完整的stderr
的唯一方法是手动缓冲它。不过,您编辑的代码应该允许您在 Kue
中看到孩子的 stderr
,而无需将其传递给 done()
回调。
但如果我不将它传递给 done(),它希望成为失败事件的“解释”/“错误追溯”的一部分,只是一个正常的日志事件..?我怎样才能缓冲它?以上是关于节点 Kue 和子进程 - 从生成的进程中获取错误的主要内容,如果未能解决你的问题,请参考以下文章