feat(ngcc): lock ngcc when processing (#34722)

Previously, it was possible for multiple instance of ngcc to be running
at the same time, but this is not supported and can cause confusing and
flakey errors at build time.

Now, only one instance of ngcc can run at a time. If a second instance
tries to execute it fails with an appropriate error message.

See https://github.com/angular/angular/issues/32431#issuecomment-571825781

PR Close #34722
This commit is contained in:
Pete Bacon Darwin
2020-01-10 09:54:58 +00:00
committed by Andrew Kushnir
parent 3a6cb6a5d2
commit a107e9edc6
9 changed files with 553 additions and 33 deletions

View File

@ -13,6 +13,7 @@ import * as cluster from 'cluster';
import {Logger} from '../../logging/logger';
import {PackageJsonUpdater} from '../../writing/package_json_updater';
import {AnalyzeEntryPointsFn, CreateCompileFn, Executor} from '../api';
import {LockFile} from '../lock_file';
import {ClusterMaster} from './master';
import {ClusterWorker} from './worker';
@ -25,18 +26,19 @@ import {ClusterWorker} from './worker';
export class ClusterExecutor implements Executor {
constructor(
private workerCount: number, private logger: Logger,
private pkgJsonUpdater: PackageJsonUpdater) {}
private pkgJsonUpdater: PackageJsonUpdater, private lockFile: LockFile) {}
async execute(analyzeEntryPoints: AnalyzeEntryPointsFn, createCompileFn: CreateCompileFn):
Promise<void> {
if (cluster.isMaster) {
this.logger.debug(
`Running ngcc on ${this.constructor.name} (using ${this.workerCount} worker processes).`);
// This process is the cluster master.
const master =
new ClusterMaster(this.workerCount, this.logger, this.pkgJsonUpdater, analyzeEntryPoints);
return master.run();
return this.lockFile.lock(() => {
this.logger.debug(
`Running ngcc on ${this.constructor.name} (using ${this.workerCount} worker processes).`);
const master = new ClusterMaster(
this.workerCount, this.logger, this.pkgJsonUpdater, analyzeEntryPoints);
return master.run();
});
} else {
// This process is a cluster worker.
const worker = new ClusterWorker(this.logger, createCompileFn);