in jazelle/bin/cluster.js [29:104]
async function runMaster() {
const groups = JSON.parse(plan);
const group = groups[index];
const errors = [];
const availableCores = cores ? parseInt(cores, 10) : cpus().length - 1 || 1;
const {projects} = await getManifest({root});
const metas = await Promise.all(
projects.map(async dir => ({
meta: JSON.parse(await read(`${root}/${dir}/package.json`, 'utf8')),
dir: `${root}/${dir}`,
depth: 0,
}))
);
const payload = groupByDepsets({root, metas, group});
for (const data of payload) {
if (data.length > 0) {
const requiredCores = Math.min(availableCores, data.length);
const workers = [...Array(requiredCores)].map(() => fork(process.env));
await install({
root,
cwd: `${root}/${data[0].dir}`,
frozenLockfile: true,
conservative: true,
});
// setup symlinks
const map = new Map();
await Promise.all(
data.slice(1).map(async item => {
const deps = await getLocalDependencies({
dirs: projects.map(dir => `${root}/${dir}`),
target: resolve(root, item.dir),
});
for (const dep of deps) {
map.set(dep.dir, dep);
}
})
);
await setupSymlinks({root, deps: [...map.values()]});
try {
await Promise.all(
workers.map(async worker => {
while (data.length > 0) {
await new Promise(async (resolve, reject) => {
const command = data.shift();
const log = `${tmpdir()}/${Math.random() * 1e17}`;
if (worker.state === 'dead') worker = fork(process.env);
worker.send({command, log});
worker.once('exit', async () => {
// 3) ...then we collect the error from each worker...
if (await exists(log)) {
const stderr = await read(log, 'utf8');
errors.push({command, stderr});
await remove(log);
}
resolve();
});
});
}
})
);
} finally {
// 4) ...then kill the workers again (because otherwise it may stay up as zombies for whatever reason)...
for (const worker of workers) worker.kill();
}
}
}
// 5) ...finally write the full error log to the master log file that was passed by batch-test-group.js
if (errors.length > 0) await write(log, JSON.stringify(errors));
}