-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.js
executable file
·81 lines (76 loc) · 2.36 KB
/
app.js
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
const { resolve } = require('path');
const { watch } = require('chokidar');
const { spawn } = require('child_process');
const serverEntry = './server';
const appRoot = resolve(__dirname);
const [ node ] = process.argv;
const args = typeof PhusionPassenger !== 'undefined' ? [] : process.argv.slice(2);
const spawnScript = (src, ...args) => {
let child;
const run = async () => {
console.debug('Starting subprocess');
child = spawn(node, [src, ...args], { stdio: 'inherit' });
console.debug(`Subprocess started on ${child.pid}`);
};
run();
const test = async () => new Promise((resolve, reject) => {
const t = spawn(node, [src, ...args, '-t']);
const stderr = [];
t.stderr.on('data', (data) => {
stderr.push(data);
});
t.on('close', (code) => {
if (code != 0) {
reject(new Error(`Server died with errorcode: ${code}\n${stderr.join('')}`))
} else {
resolve();
}
});
});
const kill = (sig = 2) => {
if (process.platform.startsWith('win')) {
console.debug(`Killing ${child.pid} with taskkill`);
spawn('taskkill', ['/pid', child.pid, '/f', '/t']);
} else {
console.debug(`Killing ${child.pid}`);
child.kill(sig);
}
}
const restart = async (sig, ...args) => {
try {
await test();
if (child.exitCode !== null) return run();
child.on('close', () => setTimeout(run, 250));
kill(sig);
} catch (e) {
console.log('Restart failed; leaving old server running.', e);
}
};
return { kill, restart };
};
const scheduled = (fn, timeout = 250) => {
let handle = null;
return () => {
if (handle) {
clearTimeout(handle);
handle = null;
}
handle = setTimeout(() => {
handle = null;
fn();
}, timeout);
}
};
const watchServer = handler => (
watch(resolve(appRoot, serverEntry), { recursive: true, encoding: 'utf-8' })
.on('raw', handler)
);
if (typeof PhusionPassenger !== 'undefined') {
console.log('Starting app from DreamHost');
watchServer(scheduled(() => writeFileSync(resolve(appRoot, '../tmp/restart.txt'), '', enc)));
require(serverEntry);
} else {
console.log('Starting app as native');
const { restart } = spawnScript(resolve(appRoot, serverEntry), ...args);
watchServer(scheduled(() => restart()));
}