UNPKG

4.58 kBJavaScriptView Raw
1'use strict'
2
3const log = require('debug')('interactor:pm2:interface')
4const path = require('path')
5const async = require('async')
6const fs = require('fs')
7const cst = require('../constants')
8
9module.exports = class PM2Interface {
10 constructor (rpc) {
11 log('PM2Interface instantiate')
12 this.rpc = rpc
13 }
14
15 getProcessByName (name, cb) {
16 var foundProc = []
17
18 this.rpc.getMonitorData({}, (err, list) => {
19 if (err) {
20 log('Error retrieving process list: ' + err)
21 return cb(err)
22 }
23
24 list.forEach((proc) => {
25 if (proc.pm2_env.name === name || proc.pm2_env.pm_exec_path === path.resolve(name.toString())) {
26 foundProc.push(proc)
27 }
28 })
29
30 return cb(null, foundProc)
31 })
32 }
33
34 /**
35 * Scale up/down a process
36 * @method scale
37 */
38 scale (opts, cb) {
39 const self = this
40 const appName = opts.name
41 let number = opts.number
42
43 function addProcs (proc, value, cb) {
44 (function ex (proc, number) {
45 if (number-- === 0) return cb()
46 log('Scaling up application')
47 self.rpc.duplicateProcessId(proc.pm2_env.pm_id, ex.bind(this, proc, number))
48 })(proc, number)
49 }
50
51 function rmProcs (procs, value, cb) {
52 let i = 0;
53
54 (function ex (procs, number) {
55 if (number++ === 0) return cb()
56 self.rpc.deleteProcessId(procs[i++].pm2_env.pm_id, ex.bind(this, procs, number))
57 })(procs, number)
58 }
59
60 let end = () => {
61 return cb ? cb(null, {success: true}) : log('Successfuly scale')
62 }
63
64 this.getProcessByName(appName, (err, procs) => {
65 if (err) {
66 return cb ? cb(err) : log(err)
67 }
68
69 if (!procs || procs.length === 0) {
70 log('Application %s not found', appName)
71 return cb ? cb(new Error('App not found')) : log('App not found')
72 }
73
74 let procNumber = procs.length
75
76 if (typeof (number) === 'string' && number.indexOf('+') >= 0) {
77 number = parseInt(number, 10)
78 return addProcs(procs[0], number, end)
79 } else if (typeof (number) === 'string' && number.indexOf('-') >= 0) {
80 number = parseInt(number, 10)
81 return rmProcs(procs, number, end)
82 } else {
83 number = parseInt(number, 10)
84 number = number - procNumber
85
86 if (number < 0) {
87 return rmProcs(procs, number, end)
88 } else if (number > 0) {
89 return addProcs(procs[0], number, end)
90 } else {
91 log('Nothing to do')
92 return cb ? cb(new Error('Same process number')) : log('Same process number')
93 }
94 }
95 })
96 }
97
98 /**
99 * Dump current processes managed by pm2 into DUMP_FILE_PATH file
100 * @method dump
101 * @param {} cb
102 * @return
103 */
104 dump (cb) {
105 var envArr = []
106
107 this.rpc.getMonitorData({}, (err, list) => {
108 if (err) {
109 return typeof cb === 'function' ? cb(err) : false
110 }
111
112 /**
113 * Description
114 * @method end
115 * @param {} err
116 * @return
117 */
118 const end = () => {
119 // Overwrite dump file, delete if broken and exit
120 try {
121 fs.writeFileSync(cst.DUMP_FILE_PATH, JSON.stringify(envArr, '', 2))
122 } catch (e) {
123 log('Dump error', e.stack || e)
124 return cb(e)
125 }
126 return (cb) ? cb(null, {success: true}) : true
127 }
128
129 async.each(list, (app, done) => {
130 delete app.pm2_env.instances
131 delete app.pm2_env.pm_id
132 if (!app.pm2_env.pmx_module) {
133 envArr.push(app.pm2_env)
134 }
135 done()
136 }, end)
137 })
138 }
139
140 _callWithProcessId (fn, params, cb) {
141 if (params.id === undefined) {
142 this.getProcessByName(params.name, (err, processes) => {
143 if (err) return cb(err)
144
145 // in case we don't find the process ourselves
146 // we believe pm2 will find it
147 if (processes.length === 0) {
148 return fn(Object.assign({ id: params.name }, params), cb)
149 }
150
151 async.eachOf(processes, (process, _key, localCb) => {
152 params.id = process.pm_id
153 fn(params, localCb)
154 }, cb)
155 })
156 } else {
157 fn(params, cb)
158 }
159 }
160
161 restart (params, cb) {
162 this._callWithProcessId(this.rpc.restartProcessId, params, cb)
163 }
164
165 reload (params, cb) {
166 this._callWithProcessId(this.rpc.reloadProcessId, params, cb)
167 }
168
169 reset (params, cb) {
170 this._callWithProcessId(
171 (newParams, cb) => this.rpc.resetMetaProcessId(newParams.id, cb),
172 params,
173 cb
174 )
175 }
176
177 ping (params, cb) {
178 this._callWithProcessId(this.rpc.ping, params, cb)
179 }
180}