"Added delay option and improved error logging in process manager"

This commit introduces a delay option to the process manager. This option allows us to set the time delay before restarting a process that has crashed. This is useful in scenarios where an immediate restart might cause further issues or allow time for external dependencies to become available again.

It also refines the error logging by reducing the amount of crash logs printed. Now, only the last crash log is presented which aides in maintaining readability. A conflict prevention has been also added to reduce the chance of mixed usage between 'rpm' and 'rph' options.

The update also enforces tidiness by adding an extraneous file to the .gitignore list.
This commit is contained in:
Ian Wijma 2023-11-19 15:38:49 +11:00
parent 84f6c26361
commit 7a43503c52
2 changed files with 27 additions and 23 deletions

3
.gitignore vendored
View File

@ -1,3 +1,6 @@
.idea/ .idea/
node_modules/ node_modules/
out/ out/
# Random test file...
0

View File

@ -1,38 +1,42 @@
const Yargs = require('yargs'); const Yargs = require('yargs');
const {spawn} = require("child_process"); const {spawn} = require("child_process");
const SECONDS_IN_A_MINUTE = 60;
const SECONDS_IN_A_HOUR = 60 * 60;
const yargs = Yargs(process.argv.splice(2)) const yargs = Yargs(process.argv.splice(2))
.scriptName('kr') .scriptName('kr')
.usage('kr [args] <thing-to-run>') .usage('kr [args] <process-to-run>')
.option('rpm', { .option('_rpm', {
default: 0, default: 0,
description: 'The amount of Retries Per Minute, before we stop retrying', description: 'The amount of Retries Per Minute, before we stop retrying',
type: 'number' type: 'number'
}) })
.option('rph', { .option('_rph', {
default: 0, default: 0,
description: 'The amount of Retries Per Hour, before we stop retrying', description: 'The amount of Retries Per Hour, before we stop retrying',
type: 'number' type: 'number'
}) })
.option('_delay', {
default: 0,
description: 'Time in seconds we want to delay the restart with.',
type: 'number'
})
.conflicts('_rpm', '_rph')
.help(); .help();
const { _ = [], rpm, rph } = yargs.argv; const { _ = [], _rpm: rpm, _rph: rph, _delay: delay } = yargs.argv;
const [command, ...args ] = _; const [command, ...args ] = _;
if (!command) { if (!command) {
return yargs.showHelp(); return yargs.showHelp();
} }
const SECONDS_IN_A_MINUTE = 60;
const SECONDS_IN_A_HOUR = 60 * 60;
let historyMax = 4; let historyMax = 4;
let seconds = SECONDS_IN_A_MINUTE; let seconds = SECONDS_IN_A_MINUTE;
let restartName = 'minute'; let restartName = 'minute';
if (rpm && rph) { if (rpm) {
return console.error('Currently, can not define both --rpm and --rph, please choose only one.');
} else if (rpm) {
historyMax = rpm historyMax = rpm
} else if (rph) { } else if (rph) {
historyMax = rph historyMax = rph
@ -40,16 +44,12 @@ if (rpm && rph) {
restartName = 'hour' restartName = 'hour'
} }
/** /** @type {Object<number, string>} */
* @type {Object<number, string>}
*/
const history = {}; const history = {};
const getNow = () => Math.ceil(Date.now() / 1000); // Time in seconds const getNow = () => Math.ceil(Date.now() / 1000); // Time in seconds
/** /** @param {string} logs */
* @param {string} logs
*/
const pushHistory = (logs) => history[getNow() + seconds] = logs; const pushHistory = (logs) => history[getNow() + seconds] = logs;
const updateHistory = () => { const updateHistory = () => {
@ -62,8 +62,9 @@ const updateHistory = () => {
const checkHistory = () => Object.keys(history).length <= historyMax; const checkHistory = () => Object.keys(history).length <= historyMax;
const restart = () => setTimeout(() => runCommand(delay), delay * 1000);
const runCommand = () => { const runCommand = () => {
console.log(`Running ${command} ${args.join(' ')}`);
const runner = spawn(command, args); const runner = spawn(command, args);
const commandLogs = []; const commandLogs = [];
@ -93,13 +94,13 @@ const runCommand = () => {
updateHistory(); updateHistory();
if (checkHistory()) { if (checkHistory()) {
console.log('Restarting...'); console.log('Restarting...');
runCommand(); restart();
} else { } else {
console.error(`The process crashed more then ${historyMax} times in the past ${restartName}, stop retrying.`); console.error(`The process crashed more then ${historyMax} times in the past ${restartName}, stop retrying.`);
console.error(`See below the past ${historyMax} crashes:`); console.error(`See below the last crash log:`);
for (const time in history) { const keys = Object.keys(history);
console.error(`Crash @ ${time - seconds}:\n${history[time]}`); const lastKey = keys[keys.length-1];
} console.log(history[lastKey]);
} }
} }
} }