-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathmain.ts
142 lines (134 loc) · 4.54 KB
/
main.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/env node
import {ArgumentParser} from 'argparse';
import * as fs from 'fs';
import * as http from 'http';
import * as net from 'net';
import * as os from 'os';
import {real} from './command';
import {CommandFactory} from './commandfactory';
import {MasterServer} from './cluster';
import {Server} from './server';
if (fs.existsSync(__filename.replace(/\.js$/, '.ts'))) {
require('source-map-support').install();
}
const npmPackage = require('./package.json');
const parser = new ArgumentParser({description: 'Node.js server that supports the Nailgun protocol.', version: npmPackage.version});
{
const transportGroup = parser.addArgumentGroup({
description: 'Transport and address. TCP is used by default.',
title:'Transport',
});
const transport = transportGroup.addMutuallyExclusiveGroup();
transport.addArgument(['--tcp'], {
constant: '127.0.0.1:2113',
help: 'TCP address to listen to, given as ip, port, or ip:port. IP defaults to 0.0.0.0, and port defaults to 2113.',
nargs: '?',
});
transport.addArgument(['--local'], {
constant:'/tmp/nodegun.sock',
help: 'Local address to listen to. Defaults to /tmp/nodegun.sock.',
nargs:'?',
});
const debugGroup = parser.addArgumentGroup({
description: 'Optionally expose internal status information via HTTP server.',
title: 'Status',
});
const debugTransport = debugGroup.addMutuallyExclusiveGroup();
debugTransport.addArgument(['--status-tcp'], {
help: 'TCP address to listen to for status, given as ip, port, or ip:port. IP defaults to 0.0.0.0.',
metavar: 'TCP',
});
debugTransport.addArgument(['--status-local'], {
help: 'Local address to listen to for status.',
metavar: 'LOCAL',
});
parser.addArgument(['--workers'], {
constant:os.cpus().length,
help: 'If present, number of worker processes to start. A flag with no argument starts one per CPU.',
nargs:'?',
});
}
const args: {status_local:string|undefined, status_tcp:string|undefined, tcp:string|undefined, local:string|undefined, workers:number|undefined} = parser.parseArgs();
function listen(server: net.Server) {
if (args.local) {
server.listen(args.local);
} else if (args.tcp) {
const [first, second] = args.tcp.split(':', 2) as [string, string|undefined];
if (second == null) {
if (first.includes('.')) {
server.listen(2113, first);
} else {
server.listen(first);
}
} else {
server.listen(+first, second);
}
} else {
server.listen(2113);
}
}
// since Node.js sets SO_REUSEADDR for all AF_INET sockets, it seems consistent to reuse for AF_UNIX
if (args.local) {
try {
fs.unlinkSync(args.local);
} catch (e) {
if (e.code !== 'ENOENT') {
throw e;
}
}
}
let server: MasterServer | Server;
if (!args.workers || args.workers <= 0) {
server = new Server(new CommandFactory());
} else {
server = new MasterServer(require.resolve('./worker.js'), args.workers);
}
listen(server.server);
if (args.local) {
const local = args.local;
const inode = fs.statSync(local).ino;
const socketCheck = setInterval(() => {
try {
if (inode === fs.statSync(local).ino) {
return;
}
} catch (e) {
if (e.code !== 'ENOENT') {
real.stderrWrite(`${e.stack}\n`);
return;
}
}
clearInterval(socketCheck);
real.stderrWrite('Socket deleted\n');
server.shutdown();
}, 5 * 1000);
socketCheck.unref();
}
{
const statusServer = http.createServer((request, response) => {
response.writeHead(200, {'Content-Type': 'application/json'});
server.status().then(status => {
response.write(JSON.stringify(status, undefined, 4));
response.write('\n');
response.end();
});
});
statusServer.unref();
if (args.status_local) {
try {
fs.unlinkSync(args.status_local);
} catch (e) {
if (e.code !== 'ENOENT') {
throw e;
}
}
statusServer.listen(args.status_local);
} else if (args.status_tcp) {
const [first, second] = args.status_tcp.split(':', 2) as [string, string|undefined];
if (second == null) {
statusServer.listen(+first);
} else {
statusServer.listen(+first, second);
}
}
}