From eb83192369f71b66f6d6849c9b365b0b5d6dd70d Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Fri, 29 Nov 2024 12:48:33 +0100 Subject: [PATCH] execute download in parallel --- .../src/server/registry/index.ts | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/playwright-core/src/server/registry/index.ts b/packages/playwright-core/src/server/registry/index.ts index 1ee492d52e..b2ad693666 100644 --- a/packages/playwright-core/src/server/registry/index.ts +++ b/packages/playwright-core/src/server/registry/index.ts @@ -32,6 +32,7 @@ import { installDependenciesLinux, installDependenciesWindows, validateDependenc import { downloadBrowserWithProgressBar, logPolitely } from './browserFetcher'; export { writeDockerVersion } from './dependencies'; import { debugLogger } from '../../utils/debugLogger'; +import EventEmitter from 'events'; let ARCHIVE: '.tar.br' | '.zip' = '.zip'; if (process.env.PW_BROWSER_DOWNLOAD_BROTLI) @@ -946,7 +947,7 @@ export class Registry { await this._validateInstallationCache(linksDir); // Install browsers for this package. - for (const executable of executables) { + await allThrottled(executables, async executable => { if (!executable._install) throw new Error(`ERROR: Playwright does not support installing ${executable.name}`); @@ -970,7 +971,7 @@ export class Registry { ].join('\n'), 1)); } await executable._install(); - } + }, ARCHIVE === '.tar.br' ? os.availableParallelism() : 1); } catch (e) { if (e.code === 'ELOCKED') { const rmCommand = process.platform === 'win32' ? 'rm -R' : 'rm -rf'; @@ -1272,4 +1273,21 @@ function lowercaseAllKeys(json: any): any { return result; } +async function allThrottled(items: T[], fn: (item: T) => Promise, concurrency: number) { + const state = { budget: concurrency }; + const event = new EventEmitter(); + await Promise.all(items.map(async item => { + while (state.budget < 1) + await new Promise(f => event.once('done', f)); + + try { + state.budget--; + return fn(item); + } finally { + state.budget++; + event.emit('done'); + } + })); +} + export const registry = new Registry(require('../../../browsers.json'));