UNPKG

pm2

Version:

Production process manager for Node.JS applications with a built-in load balancer.

116 lines (100 loc) 3.12 kB
'use strict' const cluster = require('cluster') const Debug = require('debug') const EventEmitter = require('events').EventEmitter class IPCTransport extends EventEmitter { constructor () { super() this.initiated = false this.logger = Debug('axm:transport:ipc') this.onMessage = undefined this.autoExitHandle = undefined } init (config) { this.logger('Init new transport service') if (this.initiated === true) { console.error('Trying to re-init the transport, please avoid') return this } this.initiated = true this.logger('Agent launched') this.onMessage = (data) => { this.logger('Received reverse message from IPC') this.emit('data', data) } process.on('message', this.onMessage) if (cluster.isWorker === false) { this.autoExitHook() } return this } autoExitHook () { this.autoExitHandle = setInterval(() => { const currentProcess = (cluster.isWorker) ? cluster.worker.process : process if (currentProcess._getActiveHandles().length === 3) { const handlers = currentProcess._getActiveHandles().map(h => h.constructor.name) if (handlers.includes('Pipe') === true && handlers.includes('Socket') === true) { process.removeListener('message', this.onMessage) const tmp = setTimeout(_ => { this.logger('Still alive, listen back to IPC') process.on('message', this.onMessage) }, 200) tmp.unref() } } }, 3000) this.autoExitHandle.unref() } setMetrics (metrics) { const serializedMetric = metrics.reduce((object, metric) => { if (typeof metric.name !== 'string') return object object[metric.name] = { historic: metric.historic, unit: metric.unit, type: metric.id, value: metric.value } return object }, {}) this.send('axm:monitor', serializedMetric) } addAction (action) { this.logger(`Add action: ${action.name}:${action.type}`) this.send('axm:action', { action_name: action.name, action_type: action.type, arity: action.arity, opts: action.opts }) } setOptions (options) { this.logger(`Set options: [${Object.keys(options).join(',')}]`) return this.send('axm:option:configuration', options) } send (channel, payload) { if (typeof process.send !== 'function') return -1 if (process.connected === false) { console.error('Process disconnected from parent! (not connected)') return process.exit(1) } try { this.logger(`Send on channel ${channel}`) process.send({ type: channel, data: payload }) } catch (err) { this.logger('Process disconnected from parent !') this.logger(err) return process.exit(1) } } destroy () { if (this.onMessage !== undefined) { process.removeListener('message', this.onMessage) } if (this.autoExitHandle !== undefined) { clearInterval(this.autoExitHandle) } this.logger('destroy') } } module.exports = { IPCTransport }