UNPKG

guvnor

Version:

A node process manager that isn't spanners all the way down

172 lines (139 loc) 4.36 kB
var Autowire = require('wantsit').Autowire var async = require('async') var Actions = function () { this._connectOrStart = Autowire this._logger = Autowire this._config = Autowire this._user = Autowire this._group = Autowire } Actions.prototype._parseStartProcessOpts = function (options) { var opts = { user: options.user || this._user.name, group: options.group || this._group.name, instances: options.instances || undefined, name: options.name || undefined, argv: options.argv || undefined, execArgv: options.execArgv || undefined, debug: options.debug || undefined, env: options.env || process.env } // resolve conflict with commander's name() method if (opts.name && typeof opts.name !== 'string') { delete opts.name } for (var key in opts) { if (opts[key] === undefined) { delete opts[key] } } return opts } Actions.prototype._do = function (options, callback) { this._connectOrStart(function (error, guvnor) { if (error) { throw error } this._logMessages(guvnor) callback(guvnor) }.bind(this)) } Actions.prototype._doAdmin = function (operation, options, callback) { this._connectOrStart(function (error, guvnor) { if (error) { throw error } this._logMessages(guvnor) if (guvnor[operation]) { callback(guvnor) } else { this._logger.warn('You do not appear to have sufficient permissions') guvnor.disconnect() } }.bind(this)) } Actions.prototype._logMessages = function (guvnor) { guvnor.on('*', function () { var args = [] Array.prototype.slice.call(arguments).forEach(function (arg) { try { var str = JSON.stringify(arg) if (!str) { return } var maxLength = 20000 args.push(str.length > maxLength ? str.substr(0, maxLength) + '...' : str) } catch(e) { args.push('Could not serialise - ' + e.message) } }) this._logger.debug.apply(this._logger, args) }.bind(this)) } Actions.prototype._withEach = function (pidOrNames, options, withEach, afterAll) { if (!Array.isArray(pidOrNames)) { pidOrNames = [pidOrNames] } pidOrNames = pidOrNames.map(function (pidOrName) { pidOrName = pidOrName.toString().trim() // does it contain non-numeric characters? if (pidOrName.match(/\D/)) { return pidOrName } // is it a number? var pid = parseInt(pidOrName, 10) return isNaN(pid) ? pidOrName : pid }) afterAll = afterAll || function (errors) { if (errors.length) { throw errors[0] } } this._do(options, function (guvnor) { guvnor.listProcesses(function (error, processes) { if (error) { throw error } var tasks = [] var errors = [] pidOrNames.forEach(function (pidOrName) { processes.forEach(function (managedProcess) { var name = managedProcess.name if (managedProcess.cluster) { // remove the 'Cluster: ' from the cluster manager's name name = name.substring('Cluster: '.length) } if (name === pidOrName || managedProcess.pid === pidOrName || pidOrName === '*') { tasks.push(function (managedProcess, callback) { withEach(managedProcess, guvnor, function (error) { if (managedProcess && managedProcess.disconnect) { managedProcess.disconnect(function (error) { if (error) { this._logger.debug('Error disconnecting from remote process', managedProcess.name, error) } else { this._logger.debug('Disconnected from remote process', managedProcess.name) } }.bind(this)) } if (error) { this._logger.debug(error) errors.push(error) } callback() }.bind(this)) }.bind(this, managedProcess)) } }.bind(this)) }.bind(this)) async.parallel(tasks, function (error) { if (error) { errors.push(error) } guvnor.disconnect(function () { afterAll(errors) }) }) }.bind(this)) }.bind(this)) } module.exports = Actions