Move child process handling into its own module
This commit is contained in:
parent
9caabf3be0
commit
3d76205c80
73
jukebox/children.js
Normal file
73
jukebox/children.js
Normal file
@ -0,0 +1,73 @@
|
||||
const spawn = require('child_process').spawn;
|
||||
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
|
||||
const TAGREADER = 'tagreader';
|
||||
const MP3PLAYER = 'mpg321';
|
||||
|
||||
const child_processes = new Map();
|
||||
|
||||
function launchChild(name, command) {
|
||||
var cmd = command[0],
|
||||
args = command.slice(1);
|
||||
|
||||
return spawn(cmd, args);
|
||||
}
|
||||
|
||||
function setupEmitter(name, emitter, child) {
|
||||
exports[name] = emitter;
|
||||
|
||||
child.on('error', function(err) {
|
||||
emitter.emit('process_error', err);
|
||||
});
|
||||
|
||||
child.on('close', function(code, signal) {
|
||||
emitter.emit('close', code, signal);
|
||||
});
|
||||
|
||||
child.stdout.on('data', (data) => {
|
||||
var s = data.toString(), lines = s.split(/\n/g);
|
||||
for (var i = 0, l = lines.length; i < l; i++) {
|
||||
emitter.emit('message', lines[i]);
|
||||
}
|
||||
});
|
||||
|
||||
child.stderr.on('data', (data) => {
|
||||
emitter.emit('error', data);
|
||||
});
|
||||
|
||||
return emitter;
|
||||
}
|
||||
|
||||
exports.init = function(config) {
|
||||
// Set up tag reader
|
||||
var tagreader = launchChild(TAGREADER, config.tag_reader);
|
||||
var tagreader_emitter = new EventEmitter();
|
||||
setupEmitter(TAGREADER, tagreader_emitter, tagreader);
|
||||
|
||||
child_processes.set(TAGREADER, tagreader);
|
||||
exports.tagreader = tagreader_emitter;
|
||||
|
||||
// set up mp3 player
|
||||
var mp3player = launchChild(MP3PLAYER, config.mpg321);
|
||||
var mp3player_emitter = new EventEmitter();
|
||||
setupEmitter(MP3PLAYER, mp3player_emitter, mp3player);
|
||||
|
||||
child_processes.set(MP3PLAYER, mp3player);
|
||||
exports.mp3player = mp3player_emitter;
|
||||
};
|
||||
|
||||
exports.exitHandler = function(options, err) {
|
||||
console.log('[player] closing children');
|
||||
if (err) console.log(err.stack);
|
||||
|
||||
child_processes.forEach((p) => {
|
||||
p.kill();
|
||||
});
|
||||
|
||||
if (options.exit) {
|
||||
process.exit();
|
||||
}
|
||||
};
|
||||
|
||||
// vim:set ts=2 sw=2 et:
|
70
player.js
70
player.js
@ -2,9 +2,6 @@
|
||||
const config = require('./config.json')
|
||||
|
||||
const glob = require('glob');
|
||||
const spawn = require('child_process').spawn;
|
||||
const tag_reader = spawn(config.tag_reader[0], config.tag_reader.slice(1));
|
||||
const player = spawn(config.mpg321[0], config.mpg321.slice(1));
|
||||
|
||||
const express = require('express');
|
||||
const logger = require('morgan')
|
||||
@ -12,6 +9,8 @@ const mustache = require('mustache');
|
||||
|
||||
const readFileSync = require('fs').readFileSync;
|
||||
|
||||
const children = require('./jukebox/children');
|
||||
|
||||
var app = express();
|
||||
var server = require('http').createServer();
|
||||
|
||||
@ -28,37 +27,32 @@ mustache.parse(log_tpl);
|
||||
|
||||
var play_log = [];
|
||||
|
||||
function exitHandler(options, err) {
|
||||
console.log('[player] closing children');
|
||||
if (err) console.log(err.stack);
|
||||
tag_reader.kill();
|
||||
player.kill();
|
||||
if (options.exit) {
|
||||
process.exit();
|
||||
}
|
||||
children.init(config);
|
||||
|
||||
process.on('exit', children.exitHandler.bind(null));
|
||||
process.on('SIGINT', children.exitHandler.bind(null, {exit:true}));
|
||||
|
||||
function setupChildLogging(name, child) {
|
||||
child.on('process_error', (err) => {
|
||||
console.log(`[${name}] error=${err}`);
|
||||
});
|
||||
|
||||
child.on('close', (code, signal) => {
|
||||
console.log(`[${name}] process closed:code=${code} signal=${signal}`);
|
||||
});
|
||||
|
||||
child.on('error', (data) => {
|
||||
console.log(`[${name}] stderr: ${data}`);
|
||||
});
|
||||
}
|
||||
|
||||
process.on('exit', exitHandler.bind(null));
|
||||
process.on('SIGINT', exitHandler.bind(null, {exit:true}));
|
||||
setupChildLogging('tagreader', children.tagreader);
|
||||
setupChildLogging('mp3player', children.mp3player);
|
||||
|
||||
tag_reader.on('error', function(err) {
|
||||
console.log(`[tag_reader] error=${err}`);
|
||||
children.tagreader.on('message', (data) => {
|
||||
processLine(data);
|
||||
});
|
||||
|
||||
player.on('error', function(err) {
|
||||
console.log(`[mpg321] error=${err}`);
|
||||
});
|
||||
|
||||
tag_reader.on('close', function(code, signal) {
|
||||
console.log(`[tag_reader] process closed:code=${code} signal=${signal}`);
|
||||
});
|
||||
|
||||
player.on('close', function(code, signal) {
|
||||
console.log(`[mpg321] process closed:code=${code} signal=${signal}`);
|
||||
});
|
||||
|
||||
// player.stdin.write("GAIN 100");
|
||||
|
||||
var last_tag = null;
|
||||
var debounce_until = 0;
|
||||
|
||||
@ -115,24 +109,6 @@ function processLine(data) {
|
||||
});
|
||||
}
|
||||
|
||||
tag_reader.stdout.on('data', (data) => {
|
||||
var s = data.toString(), lines = s.split(/\n/g);
|
||||
for (var i = 0, l = lines.length; i < l; i++) {
|
||||
processLine(lines[i]);
|
||||
}
|
||||
});
|
||||
|
||||
tag_reader.stderr.on('data', (data) => {
|
||||
console.log(`[tag_reader:stderr] ${data}`);
|
||||
});
|
||||
|
||||
player.stderr.on('data', (data) => {
|
||||
if (String(data).substr(0, 3) === "@F ") {
|
||||
return;
|
||||
}
|
||||
console.log(`[mpg321] stderr ${data}`);
|
||||
});
|
||||
|
||||
app.use(logger('dev'))
|
||||
app.use(express.static(__dirname + '/static'))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user