Formatting and workflow organization changes

This commit is contained in:
00Fjongl 2024-08-08 23:10:58 -05:00
parent 461c89212f
commit 8c9f79d3e7
13 changed files with 1010 additions and 979 deletions

View file

@ -4,7 +4,7 @@ import { fileURLToPath } from 'node:url';
import { build } from 'esbuild';
import ecosystem from './ecosystem.config.js';
// Some necessary constants are copied over from /src/server.mjs.
// Some necessary constants are copied over from /src/server.mjs.
const config = Object.freeze(
JSON.parse(await readFile(new URL('./src/config.json', import.meta.url)))
@ -27,12 +27,12 @@ const serverUrl = ((base) => {
const shutdown = fileURLToPath(new URL('./src/.shutdown', import.meta.url));
// Run each command line argument passed after node run-command.mjs.
// Commands are defined in the switch case statement below.
// Run each command line argument passed after node run-command.mjs.
// Commands are defined in the switch case statement below.
commands: for (let i = 2; i < process.argv.length; i++)
switch (process.argv[i]) {
// Commmand to boot up the server. Use PM2 to run if production is true in the
// config file.
// Commmand to boot up the server. Use PM2 to run if production is true in the
// config file.
case 'start':
if (config.production)
exec(
@ -42,8 +42,8 @@ commands: for (let i = 2; i < process.argv.length; i++)
console.log(stdout);
}
);
// Handle setup on Windows differently from platforms with POSIX-compliant shells.
// This should run the server as a background process.
// Handle setup on Windows differently from platforms with POSIX-compliant
// shells. This should run the server as a background process.
else if (process.platform === 'win32')
exec('START /MIN "" node backend.js', (error, stdout) => {
if (error) {
@ -52,48 +52,29 @@ commands: for (let i = 2; i < process.argv.length; i++)
}
console.log(stdout);
});
// The following approach (and similar approaches) will not work on Windows,
// because exiting this program will also terminate backend.js on Windows.
// The following approach (and similar approaches) will not work on Windows,
// because exiting this program will also terminate backend.js on Windows.
else {
const server = fork(
fileURLToPath(new URL('./backend.js', import.meta.url)),
{
cwd: process.cwd(),
stdio: ['inherit', 'pipe', 'pipe', 'ipc'],
detached: true
}
{ cwd: process.cwd(), detached: true }
);
server.stderr.on("data", stderr => {
console.error(stderr.toString());
if (stderr.toString().indexOf("DeprecationWarning") + 1)
return;
server.stderr.destroy();
process.exitCode = 1;
});
server.stdout.on("data", () => {
server.kill();
const server2 = fork(
fileURLToPath(new URL('./backend.js', import.meta.url)),
{cwd: process.cwd(), detached: true}
);
server2.unref();
server2.disconnect();
});
server.unref();
server.disconnect();
}
break;
// Stop the server. Make a temporary file that the server will check for if told
// to shut down. This is done by sending a GET request to the server.
// Stop the server. Make a temporary file that the server will check for if told
// to shut down. This is done by sending a GET request to the server.
case 'stop': {
await writeFile(shutdown, '');
let timeoutId,
hasErrored = false;
try {
// Give the server 5 seconds to respond, otherwise cancel this and throw an
// error to the console. The fetch request will also throw an error immediately
// if checking the server on localhost and the port is unused.
/* Give the server 5 seconds to respond, otherwise cancel this and throw an
* error to the console. The fetch request will also throw an error
* immediately if checking the server on localhost and the port is unused.
*/
const response = await Promise.race([
fetch(new URL('/test-shutdown', serverUrl)),
new Promise((resolve) => {
@ -105,18 +86,18 @@ commands: for (let i = 2; i < process.argv.length; i++)
clearTimeout(timeoutId);
if (response === 'Error') throw new Error('Server is unresponsive.');
} catch (e) {
// Remove the temporary shutdown file since the server didn't remove it.
// Remove the temporary shutdown file since the server didn't remove it.
await unlink(shutdown);
// Check if this is the error thrown by the fetch request for an unused port.
// Don't print the unused port error, since nothing has actually broken.
// Check if this is the error thrown by the fetch request for an unused port.
// Don't print the unused port error, since nothing has actually broken.
if (e instanceof TypeError) clearTimeout(timeoutId);
else {
console.error(e);
// Stop here unless Node will be killed later.
// Stop here unless Node will be killed later.
if (!process.argv.slice(i + 1).includes('kill')) hasErrored = true;
}
}
// Do not run this if Node will be killed later in this script. It will fail.
// Do not run this if Node will be killed later in this script. It will fail.
if (config.production && !process.argv.slice(i + 1).includes('kill'))
exec('npx pm2 stop ecosystem.config.js', (error, stdout) => {
if (error) {
@ -125,8 +106,8 @@ commands: for (let i = 2; i < process.argv.length; i++)
}
console.log(stdout);
});
// Do not continue executing commands since the server was unable to be stopped.
// Mostly implemented to prevent duplicating Node instances with npm restart.
// Do not continue executing commands since the server was unable to be stopped.
// Mostly implemented to prevent duplicating Node instances with npm restart.
if (hasErrored) {
process.exitCode = 1;
break commands;
@ -154,9 +135,10 @@ commands: for (let i = 2; i < process.argv.length; i++)
break;
}
// Kill all node processes and fully reset PM2. To be used for debugging.
// Using npx pm2 monit, or npx pm2 list in the terminal will also bring up
// more PM2 debugging tools.
/* Kill all node processes and fully reset PM2. To be used for debugging.
* Using npx pm2 monit, or npx pm2 list in the terminal will also bring up
* more PM2 debugging tools.
*/
case 'kill':
if (process.platform === 'win32')
exec(
@ -174,7 +156,57 @@ commands: for (let i = 2; i < process.argv.length; i++)
);
break;
// No default case.
case 'workflow':
if (config.production)
exec(
'npx pm2 start ecosystem.config.js --env production',
(error, stdout) => {
if (error) throw error;
console.log(stdout);
}
);
// Handle setup on Windows differently from platforms with POSIX-compliant
// shells. This should run the server as a background process.
else if (process.platform === 'win32')
exec('START /MIN "" node backend.js', (error, stdout) => {
if (error) {
console.error(error);
process.exitCode = 1;
}
console.log(stdout);
});
// The following approach (and similar approaches) will not work on Windows,
// because exiting this program will also terminate backend.js on Windows.
else {
const server = fork(
fileURLToPath(new URL('./backend.js', import.meta.url)),
{
cwd: process.cwd(),
stdio: ['inherit', 'pipe', 'pipe', 'ipc'],
detached: true,
}
);
server.stderr.on('data', (stderr) => {
console.error(stderr.toString());
if (stderr.toString().indexOf('DeprecationWarning') + 1) return;
server.stderr.destroy();
process.exitCode = 1;
});
server.stdout.on('data', () => {
server.kill();
const server2 = fork(
fileURLToPath(new URL('./backend.js', import.meta.url)),
{ cwd: process.cwd(), detached: true }
);
server2.unref();
server2.disconnect();
});
server.unref();
server.disconnect();
}
break;
// No default case.
}
process.exitCode = process.exitCode || 0;
process.exitCode = process.exitCode || 0;