From 8c485b8e7826aa994b0fac396c8afbd833ae70c1 Mon Sep 17 00:00:00 2001 From: Marcin Panek Date: Fri, 27 Sep 2024 09:46:29 +0200 Subject: [PATCH 1/3] Normalized concurrency to always be integer in `executeInParallel()`. --- .../ckeditor5-dev-release-tools/lib/utils/executeinparallel.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ckeditor5-dev-release-tools/lib/utils/executeinparallel.js b/packages/ckeditor5-dev-release-tools/lib/utils/executeinparallel.js index 57bee865a..0ffac7661 100644 --- a/packages/ckeditor5-dev-release-tools/lib/utils/executeinparallel.js +++ b/packages/ckeditor5-dev-release-tools/lib/utils/executeinparallel.js @@ -48,6 +48,7 @@ export default async function executeInParallel( options ) { concurrency = os.cpus().length / 2 } = options; + const concurrencyAsInteger = Math.floor( concurrency ) || 1; const normalizedCwd = upath.toUnix( cwd ); const packages = ( await glob( `${ packagesDirectory }/*/`, { cwd: normalizedCwd, @@ -58,7 +59,7 @@ export default async function executeInParallel( options ) { packages.filter( packagesDirectoryFilter ) : packages; - const packagesInThreads = getPackagesGroupedByThreads( packagesToProcess, concurrency ); + const packagesInThreads = getPackagesGroupedByThreads( packagesToProcess, concurrencyAsInteger ); const callbackModule = upath.join( cwd, crypto.randomUUID() + '.mjs' ); await fs.writeFile( callbackModule, `export default ${ taskToExecute };`, 'utf-8' ); From c6ffb35970cbdb01d04dff7f40665990f72fe160 Mon Sep 17 00:00:00 2001 From: Marcin Panek Date: Fri, 27 Sep 2024 09:56:51 +0200 Subject: [PATCH 2/3] Added tests for concurrency in `executeInParallel()`. --- .../tests/utils/executeinparallel.js | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/packages/ckeditor5-dev-release-tools/tests/utils/executeinparallel.js b/packages/ckeditor5-dev-release-tools/tests/utils/executeinparallel.js index 0b959df91..9cb14ab43 100644 --- a/packages/ckeditor5-dev-release-tools/tests/utils/executeinparallel.js +++ b/packages/ckeditor5-dev-release-tools/tests/utils/executeinparallel.js @@ -334,6 +334,56 @@ describe( 'executeInParallel()', () => { await promise; } ); + it( 'should use number of cores divided by two as default (`concurrency`)', async () => { + const promise = executeInParallel( defaultOptions ); + await delay( 0 ); + + expect( stubs.WorkerMock.instances ).toHaveLength( 2 ); + + // Workers did not emit an error. + for ( const worker of stubs.WorkerMock.instances ) { + getExitCallback( worker )( 0 ); + } + + await promise; + } ); + + it( 'should round down to the closest integer (`concurrency`)', async () => { + const options = Object.assign( {}, defaultOptions, { + concurrency: 3.5 + } ); + + const promise = executeInParallel( options ); + await delay( 0 ); + + expect( stubs.WorkerMock.instances ).toHaveLength( 3 ); + + // Workers did not emit an error. + for ( const worker of stubs.WorkerMock.instances ) { + getExitCallback( worker )( 0 ); + } + + await promise; + } ); + + it( 'should assign at least one thread even if concurrency is 0 (`concurrency`)', async () => { + const options = Object.assign( {}, defaultOptions, { + concurrency: 0 + } ); + + const promise = executeInParallel( options ); + await delay( 0 ); + + expect( stubs.WorkerMock.instances ).toHaveLength( 1 ); + + // Workers did not emit an error. + for ( const worker of stubs.WorkerMock.instances ) { + getExitCallback( worker )( 0 ); + } + + await promise; + } ); + it( 'should resolve the promise if a worker finished (aborted) with a non-zero exit code (first worker)', async () => { const promise = executeInParallel( defaultOptions ); await delay( 0 ); From 12aac75b8946ca1b21090d4992261890c60b93ad Mon Sep 17 00:00:00 2001 From: Marcin Panek Date: Fri, 27 Sep 2024 11:16:56 +0200 Subject: [PATCH 3/3] Amended test in `executeInParallel()` to check odd core numbers as default. --- .../tests/utils/executeinparallel.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/ckeditor5-dev-release-tools/tests/utils/executeinparallel.js b/packages/ckeditor5-dev-release-tools/tests/utils/executeinparallel.js index 9cb14ab43..2b88c78cb 100644 --- a/packages/ckeditor5-dev-release-tools/tests/utils/executeinparallel.js +++ b/packages/ckeditor5-dev-release-tools/tests/utils/executeinparallel.js @@ -8,6 +8,7 @@ import { glob } from 'glob'; import fs from 'fs/promises'; import { registerAbortController, deregisterAbortController } from '../../lib/utils/abortcontroller.js'; import executeInParallel from '../../lib/utils/executeinparallel.js'; +import os from 'os'; const stubs = vi.hoisted( () => ( { WorkerMock: class { @@ -335,10 +336,12 @@ describe( 'executeInParallel()', () => { } ); it( 'should use number of cores divided by two as default (`concurrency`)', async () => { + vi.mocked( os.cpus ).mockReturnValue( new Array( 7 ) ); + const promise = executeInParallel( defaultOptions ); await delay( 0 ); - expect( stubs.WorkerMock.instances ).toHaveLength( 2 ); + expect( stubs.WorkerMock.instances ).toHaveLength( 3 ); // Workers did not emit an error. for ( const worker of stubs.WorkerMock.instances ) {