2

我尝试通过带有 Kue 的作业队列生成一个执行 cpu 密集型计算的子进程。我目前的代码如下所示:

消费者.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)并从生成的进程中获取标准错误?

4

1 回答 1

1

您可以使用job.log方法将数据直接发送到Kue.

我还建议您从 to 切换.spawn.exec因为它在最终回调中返回stdoutstderr作为字符串以及 good 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();
    }
  });
});

我还建议使用closeevent 而不是exit,因为它等待孩子的stdio流。

有关更多信息,请参阅Event: 'exit'文档

此事件在子进程结束后发出。

请注意,子进程 stdio 流可能仍处于打开状态。

Event: 'close'文档

当子进程的 stdio 流全部终止时会发出此事件。

于 2014-08-17T01:21:03.317 回答