UNPKG

3.06 kBJavaScriptView Raw
1'use strict'
2
3const axon = require('pm2-axon')
4const cst = require('../constants.js')
5const rpc = require('pm2-axon-rpc')
6const log = require('debug')('interactor:pm2:client')
7const EventEmitter = require('events').EventEmitter
8const PM2Interface = require('./PM2Interface')
9
10/**
11 * PM2 API Wrapper used to setup connection with the daemon
12 * @param {Object} opts options
13 * @param {String} opts.sub_port socket file of the PM2 bus [optionnal]
14 * @param {String} opts.rpc_port socket file of the PM2 RPC server [optionnal]
15 */
16module.exports = class PM2Client extends EventEmitter {
17 constructor (opts) {
18 super()
19 const subSocket = (opts && opts.sub_port) || cst.DAEMON_PUB_PORT
20 const rpcSocket = (opts && opts.rpc_port) || cst.DAEMON_RPC_PORT
21
22 const sub = axon.socket('sub-emitter')
23 this.sub_sock = sub.connect(subSocket)
24 this.bus = sub
25
26 const req = axon.socket('req')
27 this.rpc_sock = req.connect(rpcSocket)
28 this.rpc_client = new rpc.Client(req)
29
30 this.rpc = {}
31
32 this.rpc_sock.on('connect', _ => {
33 log('PM2 API Wrapper connected to PM2 Daemon via RPC')
34 this.generateMethods(_ => {
35 this.pm2Interface = new PM2Interface(this.rpc)
36 this.emit('ready')
37 })
38 })
39
40 this.rpc_sock.on('close', _ => {
41 log('pm2 rpc closed')
42 this.emit('closed')
43 })
44
45 this.rpc_sock.on('reconnect attempt', _ => {
46 log('pm2 rpc reconnecting')
47 this.emit('reconnecting')
48 })
49
50 this.sub_sock.on('connect', _ => {
51 log('bus ready')
52 this.emit('bus:ready')
53 })
54
55 this.sub_sock.on('close', _ => {
56 log('bus closed')
57 this.emit('bus:closed')
58 })
59
60 this.sub_sock.on('reconnect attempt', _ => {
61 log('bus reconnecting')
62 this.emit('bus:reconnecting')
63 })
64 }
65
66 /**
67 * Disconnect socket connections. This will allow Node to exit automatically.
68 * Further calls to PM2 from this object will throw an error.
69 */
70 disconnect () {
71 this.sub_sock.close()
72 this.rpc_sock.close()
73 }
74
75 /**
76 * Generate method by requesting exposed methods by PM2
77 * You can now control/interact with PM2
78 */
79 generateMethods (cb) {
80 log('Requesting and generating RPC methods')
81 this.rpc_client.methods((err, methods) => {
82 if (err) return cb(err)
83 Object.keys(methods).forEach((key) => {
84 let method = methods[key]
85
86 log('+-- Creating %s method', method.name);
87
88 ((name) => {
89 const self = this
90 this.rpc[name] = function () {
91 let args = Array.prototype.slice.call(arguments)
92 args.unshift(name)
93 self.rpc_client.call.apply(self.rpc_client, args)
94 }
95 })(method.name)
96 })
97 return cb()
98 })
99 }
100
101 remote (method, parameters, cb) {
102 log('remote send %s', method, parameters)
103 if (typeof this.pm2Interface[method] === 'undefined') {
104 return cb(new Error('Deprecated or invalid method'))
105 }
106 this.pm2Interface[method](parameters, cb)
107 }
108
109 msgProcess (data, cb) {
110 this.rpc.msgProcess(data, cb)
111 }
112}