lib/project-lifecycle-process-witness.js
Rama main · réplica de lectura del repositorio original.
// Bounded, content-free process identities for closure reconciliation after host exit.
var cp = require('child_process');
function table() {
var output = cp.execFileSync('ps', ['-axo', 'pid=,ppid=,lstart='], { encoding: 'utf8', timeout: 5000, maxBuffer: 8 * 1024 * 1024, env: Object.assign({}, process.env, { LC_ALL: 'C', TZ: 'UTC' }) });
var rows = new Map();
output.split('\n').forEach(function (line) {
var match = /^\s*(\d+)\s+(\d+)\s+(.+?)\s*$/.exec(line);
if (match) rows.set(Number(match[1]), { pid: Number(match[1]), parent: Number(match[2]), start: match[3] });
});
if (!rows.has(process.pid)) throw new Error("The process identity census was incomplete.");
return rows;
}
function capture() {
try {
var rows = table(), host = rows.get(process.pid), children = [], parents = new Set([process.pid]);
if (!host) return null;
for (var pass = 0; pass < rows.size; pass++) {
var changed = false;
rows.forEach(function (row) { if (parents.has(row.parent) && !parents.has(row.pid)) { parents.add(row.pid); children.push(row); changed = true; } });
if (!changed) break;
}
return { host: host, children: children };
} catch (error) { return null; }
}
function confirmsExit(witness) {
if (!witness || !witness.host || !Array.isArray(witness.children)) return false;
var rows = table();
return [witness.host].concat(witness.children).every(function (previous) {
var current = rows.get(previous.pid); return !current || current.start !== previous.start;
});
}
module.exports = { capture: capture, confirmsExit: confirmsExit };