2

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 を取得するより良い方法はありますか?

4

1 に答える 1

1

job.logメソッドを使用して、データを に直接送信できますKue

.spawnまた、 からに切り替えることをお勧めします。これは、最終コールバックで文字列としてandを.exec返すため、ニーズに適した good と一緒に返すためです。stdoutstderrerror

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.logjob.log

stderrただし、1 つのチャンクで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代わりに event を使用することもお勧めします。exitstdio

詳細については、Event: 'exit'ドキュメントを参照してください。

このイベントは、子プロセスが終了した後に発行されます。

子プロセスの stdio ストリームがまだ開いている可能性があることに注意してください。

およびEvent: 'close'ドキュメント:

このイベントは、子プロセスの stdio ストリームがすべて終了したときに発行されます。

于 2014-08-17T01:21:03.317 に答える