64 lines
1.7 KiB
JavaScript
64 lines
1.7 KiB
JavaScript
"use strict";
|
|
|
|
// TODO: These should really be their own individual classes. Are
|
|
// there enough commonalities to warrant a base class?
|
|
|
|
const { spawn } = require('child_process');
|
|
const { EventEmitter } = require('events');
|
|
|
|
module.exports.ChildProcessEmitter = class ChildProcessEmitter extends EventEmitter {
|
|
constructor(command, logger) {
|
|
super();
|
|
|
|
var emitter = this;
|
|
|
|
this.transform_line = l => l;
|
|
|
|
this.logger = logger;
|
|
this.stderrFilters = [];
|
|
|
|
var cmd = command[0],
|
|
args = command.slice(1);
|
|
|
|
this.childProcess = spawn(cmd, args);
|
|
|
|
this.childProcess.on('error', function(err) {
|
|
emitter.logger.error("process error", { class: emitter.constructor.name, err: String(err).trim() });
|
|
});
|
|
|
|
this.childProcess.on('close', function(code, signal) {
|
|
emitter.logger.debug("process closed", { class: emitter.constructor.name, code: code, signal: signal });
|
|
});
|
|
|
|
this.childProcess.stdout.on('data', (data) => {
|
|
var lines = data.toString().split(/\n/g);
|
|
lines.map(line => line.trim())
|
|
.filter(line => line.length)
|
|
.map(this.transform_line)
|
|
.map(line => this.emit('message', line));
|
|
});
|
|
|
|
this.childProcess.stderr.on('data', (data) => {
|
|
var line = data.toString().trim();
|
|
var filtered = this.stderrFilters.reduce((filter, filtered) => {
|
|
return filtered || filter(line);
|
|
}, false);
|
|
if (filtered) {
|
|
return;
|
|
}
|
|
emitter.logger.error('process stderr', { class: emitter.constructor.name, stderr: line});
|
|
});
|
|
}
|
|
|
|
kill() {
|
|
this.logger.debug("killing child process");
|
|
this.childProcess.kill();
|
|
}
|
|
|
|
send(message) {
|
|
this.childProcess.stdin.write(message);
|
|
}
|
|
}
|
|
|
|
// vim:set ts=2 sw=2 et:
|