weaver
Version:
Interactive process management system
200 lines (176 loc) • 5.41 kB
JavaScript
// Generated by CoffeeScript 1.11.0
var EventEmitter, Task, Watcher, Weaver, assert, resolve, schema, validator, zs,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
assert = require('assert');
resolve = require('path').resolve;
zs = require('z-schema');
schema = require('./schema');
EventEmitter = require('events').EventEmitter;
Task = require('./task');
Watcher = require('./watcher');
validator = new zs({
strictMode: true
});
Weaver = (function(superClass) {
extend(Weaver, superClass);
Weaver.logger = function(fn) {
var i, item, len, ref;
ref = [Weaver, Task, Watcher.constructor];
for (i = 0, len = ref.length; i < len; i++) {
item = ref[i];
item.prototype.log = fn;
}
};
Weaver.prototype.version = require('../package').version;
Weaver.prototype.log = function() {};
function Weaver() {
this.on('error', this.errorHandler);
this.on('upgrade', this.upgradeHandler);
this.start = Date.now();
this.config = Object.create(null);
return this;
}
Weaver.prototype.validate = function(configuration) {
var argument, i, key, len, name, ref, ref1, task;
assert.ok(validator.validate(configuration, schema), 'Invalid configuration');
ref = configuration.tasks;
for (name in ref) {
if (!hasProp.call(ref, name)) continue;
task = ref[name];
for (key in task) {
if (!hasProp.call(task, key)) continue;
if (key === 'arguments') {
ref1 = task[key];
for (i = 0, len = ref1.length; i < len; i++) {
argument = ref1[i];
if (Array.isArray(argument)) {
assert.equal(task.count, argument.length, "Nested array in arguments should contain " + task.count + " values");
}
}
}
}
task.name = name;
}
return configuration;
};
Weaver.prototype.upgrade = function(data, path) {
var error, name, params, parts, ref, task;
parts = [path];
params = null;
try {
data = JSON.parse(data);
params = this.validate(data);
} catch (error1) {
error = error1;
error.message = "Config error: " + error.message;
this.emit('error', error);
}
if (params) {
if (params.path) {
parts.push(params.path);
}
ref = params.tasks;
for (name in ref) {
if (!hasProp.call(ref, name)) continue;
task = ref[name];
task.cwd = resolve.apply(void 0, parts.concat(task.cwd || '.'));
this.config[name] = task;
}
this.emit('upgrade');
}
};
Weaver.prototype.status = function() {
return Task.status();
};
Weaver.prototype.command = function(action, name, args) {
var fn, ref, task;
fn = Task.prototype[action + 'PID'];
if (!Array.isArray(args)) {
args = [];
}
if (typeof fn !== 'function') {
throw new Error('Unknown action ' + action);
}
if (name == null) {
ref = Task.tasks;
for (name in ref) {
if (!hasProp.call(ref, name)) continue;
task = ref[name];
fn.apply(task, args);
}
} else {
task = Task.tasks[name];
if (task) {
if (action === 'kill') {
args.unshift(null);
}
fn.apply(task, args);
} else if (Number(name) == name) {
args.unshift(Number(name));
this.command(action, null, args);
} else {
this.log('Task ' + name + ' was not found');
}
}
};
Weaver.prototype.die = function(code) {
var name, ref, task, timeout, tryExit;
code = code != null ? code : 1;
tryExit = (function(_this) {
return function() {
var i, len, name, ref, ref1, subtask, task;
ref = Task.tasks;
for (name in ref) {
if (!hasProp.call(ref, name)) continue;
task = ref[name];
ref1 = task.subtasks;
for (i = 0, len = ref1.length; i < len; i++) {
subtask = ref1[i];
if (subtask.pid) {
return;
}
}
}
_this.emit('exit', code);
};
})(this);
ref = Task.tasks;
for (name in ref) {
if (!hasProp.call(ref, name)) continue;
task = ref[name];
if (task.timeout > timeout) {
timeout = task.timeout;
}
task.dropSubtasks();
task.on('exit', tryExit);
}
setImmediate(tryExit);
};
Weaver.prototype.errorHandler = function(error) {
this.log(error.message);
};
Weaver.prototype.upgradeHandler = function() {
var name, options, ref, ref1, task;
ref = Task.tasks;
for (name in ref) {
if (!hasProp.call(ref, name)) continue;
task = ref[name];
if (!(name in this.config)) {
task.dropSubtasks();
}
}
ref1 = this.config;
for (name in ref1) {
if (!hasProp.call(ref1, name)) continue;
options = ref1[name];
task = Task.create(name);
if (!task.listeners('error').length) {
task.on('error', this.emit.bind(this, 'error'));
}
task.upgrade(options);
}
};
return Weaver;
})(EventEmitter);
module.exports = new Weaver();