Skip to content

Commit

Permalink
fix(@angular-devkit/build-angular): limit concurrent output file writ…
Browse files Browse the repository at this point in the history
…es with application builder

When using localization with the application builder for a large amount of locales, the number
of files that may need to be written to disk can become large. This may be problematic on certain
operating systems depending on the open file process limits. To avoid approaching the limit, the
number of concurrent writes is now limited to 64.
  • Loading branch information
clydin committed Oct 11, 2023
1 parent c12f98f commit 01fc188
Showing 1 changed file with 27 additions and 13 deletions.
40 changes: 27 additions & 13 deletions packages/angular_devkit/build_angular/src/tools/esbuild/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,25 +175,39 @@ export function getFeatureSupport(target: string[]): BuildOptions['supported'] {
return supported;
}

const MAX_CONCURRENT_WRITES = 64;

export async function writeResultFiles(
outputFiles: BuildOutputFile[],
assetFiles: { source: string; destination: string }[] | undefined,
outputPath: string,
) {
const directoryExists = new Set<string>();
await Promise.all(
outputFiles.map(async (file) => {
const fullOutputPath = file.fullOutputPath;
// Ensure output subdirectories exist
const basePath = path.dirname(fullOutputPath);
if (basePath && !directoryExists.has(basePath)) {
await fs.mkdir(path.join(outputPath, basePath), { recursive: true });
directoryExists.add(basePath);
}
// Write file contents
await fs.writeFile(path.join(outputPath, fullOutputPath), file.contents);
}),
);

// Writes the output file to disk and ensures the containing directories are present
const writeOutputFile = async (file: BuildOutputFile) => {
const fullOutputPath = file.fullOutputPath;
// Ensure output subdirectories exist
const basePath = path.dirname(fullOutputPath);
if (basePath && !directoryExists.has(basePath)) {
await fs.mkdir(path.join(outputPath, basePath), { recursive: true });
directoryExists.add(basePath);
}
// Write file contents
await fs.writeFile(path.join(outputPath, fullOutputPath), file.contents);
};

// Write files in groups of MAX_CONCURRENT_WRITES to avoid too many open files
for (let fileIndex = 0; fileIndex < outputFiles.length; ) {
const groupMax = Math.min(fileIndex + MAX_CONCURRENT_WRITES, outputFiles.length);

const actions = [];
while (fileIndex < groupMax) {
actions.push(writeOutputFile(outputFiles[fileIndex++]));
}

await Promise.all(actions);
}

if (assetFiles?.length) {
await Promise.all(
Expand Down

0 comments on commit 01fc188

Please sign in to comment.