monex
Version:
Execute one or multiple scripts, interactively or in daemon mode, and restart them whenever they crash or a watched file changes.
54 lines (53 loc) • 1.65 kB
JavaScript
/* IMPORT */
import cluster from 'node:cluster';
import os from 'node:os';
import path from 'node:path';
import process from 'node:process';
import { color } from 'specialist';
/* MAIN */
// The cluster controller should be spawned with the right options, and then it will spawn and respawn its workers
if (cluster.isPrimary) { // Controller, just to be sure
const options = JSON.parse(process.argv[2]);
const name = options.name;
const delay = options.delay || 1000;
const workersSize = Math.max(2, options.size || os.cpus().length);
const workers = new Set();
let exiting = false;
const setup = () => {
cluster.setupPrimary({
exec: path.resolve(process.cwd(), options.exec),
args: options.args,
windowsHide: true
});
};
const init = () => {
for (let i = 0; i < workersSize; i++) {
fork();
}
};
const fork = () => {
if (exiting)
return;
if (workers.size >= workersSize)
return;
console.log(`[monex] ${name ? `${color.bold(name)} - ` : ''}Starting cluster worker...`);
const worker = cluster.fork();
workers.add(worker);
};
const onExit = () => {
exiting = true;
for (const worker of workers) {
if (worker.isDead())
continue;
worker.kill('SIGTERM');
}
};
const onWorkerExit = (worker) => {
workers.delete(worker);
setTimeout(fork, delay); // Restarting it
};
cluster.on('exit', onWorkerExit);
process.on('SIGTERM', onExit);
setup();
init();
}