Skip to content

Commit 2663a3e

Browse files
authored
Merge pull request #267 from forty/forty/remove-optimist
Remove optimist in favor of @author.io/arg
2 parents a6c8b3d + ff48877 commit 2663a3e

File tree

2 files changed

+116
-82
lines changed

2 files changed

+116
-82
lines changed

lib/wrapper.js

Lines changed: 115 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,122 @@
11
// Handle input parameters
22
var Logger = require('./eventlog'),
3-
optimist = require('optimist'),
3+
Args = require('@author.io/args'),
44
net = require('net'),
55
max = 60,
66
p = require('path'),
7-
argv = optimist
8-
.demand('file')
9-
.alias('f','file')
10-
.describe('file','The absolute path of the script to be run as a process.')
11-
.check(function(argv){
12-
require('fs').existsSync(p.resolve(argv.f),function(exists){
13-
return exists;
14-
});
15-
})
16-
.describe('scriptoptions','The options to be sent to the script.')
17-
.alias('d','cwd')
18-
.describe('cwd','The absolute path of the current working directory of the script to be run as a process.')
19-
// .check(function(argv){
20-
// require('fs').existsSync(p.resolve(argv.d),function(exists){
21-
// return exists;
22-
// });
23-
// })
24-
.demand('log')
25-
.alias('l','log')
26-
.describe('log','The descriptive name of the log for the process')
27-
.default('eventlog','APPLICATION')
28-
.alias('e','eventlog')
29-
.describe('eventlog','The event log container. This must be APPLICATION or SYSTEM.')
30-
.default('maxretries',-1)
31-
.alias('m','maxretries')
32-
.describe('maxretries','The maximim number of times the process will be auto-restarted.')
33-
.default('maxrestarts',5)
34-
.alias('r','maxrestarts')
35-
.describe('maxrestarts','The maximim number of times the process should be restarted within a '+max+' second period shutting down.')
36-
.default('wait',1)
37-
.alias('w','wait')
38-
.describe('wait','The number of seconds between each restart attempt.')
39-
.check(function(argv){
40-
return argv.w >= 0;
41-
})
42-
.default('grow',.25)
43-
.alias('g','grow')
44-
.describe('grow','A percentage growth rate at which the wait time is increased.')
45-
.check(function(argv){
46-
return (argv.g >= 0 && argv.g <= 1);
47-
})
48-
.default('abortonerror','no')
49-
.alias('a','abortonerror')
50-
.describe('abortonerror','Do not attempt to restart the process if it fails with an error,')
51-
.check(function(argv){
52-
return ['y','n','yes','no'].indexOf(argv.a.trim().toLowerCase()) >= 0;
53-
})
54-
.default('stopparentfirst', 'no')
55-
.alias('s', 'stopparentfirst')
56-
.describe('stopparentfirst', 'Allow the script to exit using a shutdown message.')
57-
.check(function(argv){
58-
return ['y','n','yes','no'].indexOf(argv.a.trim().toLowerCase()) >= 0;
59-
})
60-
.argv,
61-
log = new Logger(argv.e == undefined ? argv.l : {source:argv.l,eventlog:argv.e}),
627
fork = require('child_process').fork,
63-
script = p.resolve(argv.f),
64-
wait = argv.w*1000,
65-
grow = argv.g+1,
668
attempts = 0,
679
startTime = null,
6810
starts = 0,
69-
child = null
11+
child = null,
7012
forcekill = false;
7113

72-
if (argv.d){
73-
if (!require('fs').existsSync(p.resolve(argv.d))){
74-
console.warn(argv.d+' not found.');
75-
argv.d = process.cwd();
14+
Args.configure({
15+
file: {
16+
type: 'string',
17+
required: true,
18+
alias: 'f',
19+
description: 'The absolute path of the script to be run as a process.',
20+
validate: function(value){
21+
require('fs').existsSync(p.resolve(value),function(exists){
22+
return exists;
23+
});
24+
}
25+
},
26+
scriptoptions: {
27+
type: 'string',
28+
description: 'The options to be sent to the script.'
29+
},
30+
cwd: {
31+
type: 'string',
32+
description: 'The absolute path of the current working directory of the script to be run as a process.',
33+
alias: 'd',
34+
validate: function(value){
35+
require('fs').existsSync(p.resolve(value),function(exists){
36+
return exists;
37+
});
38+
}
39+
},
40+
log: {
41+
type: 'string',
42+
required: true,
43+
alias: 'l',
44+
description: 'The descriptive name of the log for the process'
45+
},
46+
eventlog: {
47+
type: 'string',
48+
alias: 'e',
49+
description: 'The event log container. This must be APPLICATION or SYSTEM.',
50+
defaults: 'APPLICATION'
51+
},
52+
maxretries: {
53+
type: 'number',
54+
alias: 'm',
55+
description: 'The maximim number of times the process will be auto-restarted.',
56+
defaults: -1
57+
},
58+
maxrestarts: {
59+
type: 'number',
60+
alias: 'r',
61+
description: 'The maximim number of times the process should be restarted within a '+max+' second period shutting down.',
62+
defaults: 5
63+
},
64+
wait: {
65+
type: 'number',
66+
alias: 'w',
67+
description: 'The number of seconds between each restart attempt.',
68+
defaults: 1,
69+
validate: function(value){
70+
return value >= 0;
71+
}
72+
},
73+
grow: {
74+
type: 'number',
75+
alias: 'g',
76+
description: 'A percentage growth rate at which the wait time is increased.',
77+
defaults: .25,
78+
validate: function(value){
79+
return value >= 0 && value <= 1;
80+
}
81+
},
82+
abortonerror: {
83+
type: 'string',
84+
alias: 'a',
85+
description: 'Do not attempt to restart the process if it fails with an error.',
86+
defaults: 'no',
87+
options: ['y','n','yes','no']
88+
},
89+
stopparentfirst: {
90+
type: 'string',
91+
alias: 's',
92+
decribe: 'Allow the script to exit using a shutdown message.',
93+
defaults: 'no',
94+
options: ['y','n','yes','no']
95+
}
96+
});
97+
Args.disallowUnrecognized();
98+
Args.enforceRules();
99+
100+
var argv = Args.data,
101+
log = new Logger(argv.eventlog == undefined ? argv.log : {source:argv.log,eventlog:argv.eventlog}),
102+
script = p.resolve(argv.file),
103+
wait = argv.wait*1000,
104+
grow = argv.grow+1;
105+
106+
if (argv.cwd){
107+
if (!require('fs').existsSync(p.resolve(argv.cwd))){
108+
console.warn(argv.cwd+' not found.');
109+
argv.cwd = process.cwd();
76110
}
77-
argv.d = p.resolve(argv.d);
111+
argv.cwd = p.resolve(argv.cwd);
78112
}
79113

80-
if (typeof argv.m === 'string'){
81-
argv.m = parseInt(argv.m);
114+
if (typeof argv.maxretries === 'string'){
115+
argv.maxretries = parseInt(argv.maxretries);
82116
}
83117

84118
// Set the absolute path of the file
85-
argv.f = p.resolve(argv.f);
119+
argv.file = p.resolve(argv.file);
86120

87121
// Hack to force the wrapper process to stay open by launching a ghost socket server
88122
var server = net.createServer().listen();
@@ -100,7 +134,7 @@ var monitor = function() {
100134
if(!child || !child.pid) {
101135

102136
// If the number of periodic starts exceeds the max, kill the process
103-
if (starts >= argv.r){
137+
if (starts >= argv.maxrestarts){
104138
if (new Date().getTime()-(max*1000) <= startTime.getTime()){
105139
log.error('Too many restarts within the last '+max+' seconds. Please check the script.');
106140
process.exit();
@@ -110,8 +144,8 @@ var monitor = function() {
110144
setTimeout(function(){
111145
wait = wait * grow;
112146
attempts += 1;
113-
if (attempts > argv.m && argv.m >= 0){
114-
log.error('Too many restarts. '+argv.f+' will not be restarted because the maximum number of total restarts has been exceeded.');
147+
if (attempts > argv.maxretries && argv.maxretries >= 0){
148+
log.error('Too many restarts. '+argv.file+' will not be restarted because the maximum number of total restarts has been exceeded.');
115149
process.exit();
116150
} else {
117151
launch('warn', 'Restarted ' + wait + ' msecs after unexpected exit; attempts = ' + attempts);
@@ -120,7 +154,7 @@ var monitor = function() {
120154
} else {
121155
// reset attempts and wait time
122156
attempts = 0;
123-
wait = argv.w * 1000;
157+
wait = argv.wait * 1000;
124158
}
125159
};
126160

@@ -138,7 +172,7 @@ var launch = function(logLevel, msg) {
138172
return;
139173
}
140174

141-
//log.info('Starting '+argv.f);
175+
//log.info('Starting '+argv.file);
142176
if (logLevel && msg) {
143177
log[logLevel](msg);
144178
}
@@ -156,18 +190,18 @@ var launch = function(logLevel, msg) {
156190
// Fork the child process
157191
var opts = {env:process.env};
158192
var args = [];
159-
if (argv.d) opts.cwd = argv.d;
160-
if (argv.s) opts.detached = true;
193+
if (argv.cwd) opts.cwd = argv.cwd;
194+
if (argv.stopparentfirst) opts.detached = true;
161195
if (argv.scriptoptions) args = argv.scriptoptions.split(' ');
162196
child = fork(script,args,opts);
163197

164198
// When the child dies, attempt to restart based on configuration
165199
child.on('exit',function(code){
166-
log.warn(argv.f+' stopped running.');
200+
log.warn(argv.file+' stopped running.');
167201

168202
// If an error is thrown and the process is configured to exit, then kill the parent.
169-
if (code !== 0 && argv.a == "yes"){
170-
log.error(argv.f+' exited with error code '+code);
203+
if (code !== 0 && argv.abortonerror == "yes"){
204+
log.error(argv.file+' exited with error code '+code);
171205
process.exit();
172206
//server.unref();
173207
} else if (forcekill) {
@@ -183,13 +217,13 @@ var launch = function(logLevel, msg) {
183217
var killkid = function(){
184218
forcekill = true;
185219
if (child) {
186-
if (argv.s) {
220+
if (argv.stopparentfirst) {
187221
child.send('shutdown');
188222
} else {
189223
child.kill();
190224
}
191225
} else {
192-
log.warn('Attempted to kill an unrecognized process.')
226+
log.warn('Attempted to kill an unrecognized process.');
193227
}
194228
}
195229

@@ -202,4 +236,4 @@ process.on('uncaughtException', function(err) {
202236
});
203237

204238
// Launch the process
205-
launch('info', 'Starting ' + argv.f);
239+
launch('info', 'Starting ' + argv.file);

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"main": "lib/node-windows.js",
2020
"preferGlobal": true,
2121
"dependencies": {
22-
"optimist": "~0.6.0",
22+
"@author.io/arg": "^1.3.11",
2323
"xml": "0.0.12"
2424
},
2525
"readmeFilename": "README.md",

0 commit comments

Comments
 (0)