batch-cluster
Version:
Manage a cluster of child processes
98 lines • 3.65 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.pidExists = pidExists;
exports.kill = kill;
exports.pids = pids;
const node_child_process_1 = __importDefault(require("node:child_process"));
const node_fs_1 = require("node:fs");
const promises_1 = require("node:fs/promises");
const Error_1 = require("./Error");
const Platform_1 = require("./Platform");
/**
* @param {number} pid process id. Required.
* @returns boolean true if the given process id is in the local process
* table. The PID may be paused or a zombie, though.
*/
function pidExists(pid) {
if (pid == null || !isFinite(pid) || pid <= 0)
return false;
try {
// signal 0 can be used to test for the existence of a process
// see https://nodejs.org/dist/latest-v18.x/docs/api/process.html#processkillpid-signal
return process.kill(pid, 0);
}
catch (err) {
// We're expecting err.code to be either "EPERM" (if we don't have
// permission to send `pid` and message), or "ESRCH" if that pid doesn't
// exist. EPERM means it _does_ exist!
if ((err === null || err === void 0 ? void 0 : err.code) === "EPERM")
return true;
// failed to get priority--assume the pid is gone.
return false;
}
}
/**
* Send a signal to the given process id.
*
* @export
* @param pid the process id. Required.
* @param force if true, and the current user has
* permissions to send the signal, the pid will be forced to shut down. Defaults to false.
*/
function kill(pid, force = false) {
if (pid == null || !isFinite(pid) || pid <= 0)
return false;
try {
return process.kill(pid, force ? "SIGKILL" : undefined);
}
catch (err) {
if (!String(err).includes("ESRCH"))
throw err;
return false;
// failed to get priority--assume the pid is gone.
}
}
/**
* Only used by tests
*
* @returns {Promise<number[]>} all the Process IDs in the process table.
*/
async function pids() {
// Linux‐style: read /proc
if (!Platform_1.isWin && (0, node_fs_1.existsSync)("/proc")) {
const names = await (0, promises_1.readdir)("/proc");
return names.filter((d) => /^\d+$/.test(d)).map((d) => parseInt(d, 10));
}
// fallback: ps or tasklist
const cmd = Platform_1.isWin ? "tasklist" : "ps";
const args = Platform_1.isWin ? ["/NH", "/FO", "CSV"] : ["-e", "-o", "pid="];
return new Promise((resolve, reject) => {
node_child_process_1.default.execFile(cmd, args, (err, stdout, stderr) => {
if (err)
return reject((0, Error_1.asError)(err));
if (stderr.trim())
return reject(new Error(stderr));
const pids = stdout
.trim()
.split(/[\r\n]+/)
.map((line) => {
var _a;
if (Platform_1.isWin) {
// "Image","PID",…
// split on "," and strip outer quotes:
const cols = line.split('","');
const pidStr = (_a = cols[1]) === null || _a === void 0 ? void 0 : _a.replace(/"/g, "");
return Number(pidStr);
}
// ps -o pid= gives you just the number
return Number(line.trim());
})
.filter((n) => Number.isFinite(n) && n > 0);
resolve(pids);
});
});
}
//# sourceMappingURL=Pids.js.map
;