我尝试通过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)并从生成的进程中获取stderr?
答案 0 :(得分:1)
您可以使用job.log
method将数据直接发送到Kue
。
我还建议您从.spawn
切换到.exec
,因为它会在最终回调中返回stdout
和stderr
作为字符串以及良好{{1} ,},非常适合您的需求:
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
,以便将其发送到Kue中:
stderr
我还建议使用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
个流。
有关详细信息,请参阅Event: 'exit'
docs:
在子进程结束后发出此事件。
请注意,子进程stdio流可能仍处于打开状态。
当子进程的stdio流具有此事件时,将发出此事件 全部终止。