Skip to content

Commit cd59a66

Browse files
authored
feat(core): run parallel based on the number of cpu cores (#31011)
1 parent 3f5fd89 commit cd59a66

File tree

3 files changed

+66
-4
lines changed

3 files changed

+66
-4
lines changed

docs/shared/recipes/running-tasks/run-tasks-in-parallel.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ If you want to increase the number of processes running tasks to, say, 5 (by def
1111
npx nx build myapp --parallel=5
1212
```
1313

14+
You can also set parallel based on the percentage of the number of logical CPUs.
15+
16+
```shell
17+
npx nx build myapp --parallel=50%
18+
```
19+
1420
Note, you can also change the default in `nx.json`, like this:
1521

1622
{% tabs %}

packages/nx/src/command-line/yargs-utils/shared-options.spec.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as yargs from 'yargs';
22

33
import {
4+
readParallelFromArgsAndEnv,
45
withAffectedOptions,
56
withOutputStyleOption,
67
withRunManyOptions,
@@ -130,3 +131,47 @@ describe('shared-options', () => {
130131
);
131132
});
132133
});
134+
135+
describe('readParallelFromArgsAndEnv', () => {
136+
it('default parallel should be 3', () => {
137+
const result = readParallelFromArgsAndEnv({ parallel: 'true' });
138+
expect(result).toEqual(3);
139+
});
140+
141+
it('use maxParallel', () => {
142+
const result = readParallelFromArgsAndEnv({
143+
parallel: '',
144+
maxParallel: '4',
145+
});
146+
expect(result).toEqual(4);
147+
});
148+
149+
it('use max-parallel', () => {
150+
const result = readParallelFromArgsAndEnv({
151+
parallel: '',
152+
'max-parallel': '5',
153+
});
154+
expect(result).toEqual(5);
155+
});
156+
157+
it('should read parallel 6', () => {
158+
const result = readParallelFromArgsAndEnv({
159+
parallel: '6',
160+
});
161+
expect(result).toEqual(6);
162+
});
163+
164+
it('0% parallel should be 1', () => {
165+
const result = readParallelFromArgsAndEnv({
166+
parallel: '0%',
167+
});
168+
expect(result).toEqual(1);
169+
});
170+
171+
it('100% parallel should not be less than 1', () => {
172+
const result = readParallelFromArgsAndEnv({
173+
parallel: '100%',
174+
});
175+
expect(result).toBeGreaterThanOrEqual(1);
176+
});
177+
});

packages/nx/src/command-line/yargs-utils/shared-options.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { readNxJson } from '../../config/nx-json';
22
import { shouldUseTui } from '../../tasks-runner/is-tui-enabled';
33
import { NxArgs } from '../../utils/command-line-utils';
44
import { Argv, coerce, ParserConfigurationOptions } from 'yargs';
5+
import { availableParallelism, cpus } from 'node:os';
56

67
interface ExcludeOptions {
78
exclude: string[];
@@ -380,17 +381,17 @@ export function readParallelFromArgsAndEnv(args: { [k: string]: any }) {
380381
args['parallel'] === 'true' ||
381382
args['parallel'] === true ||
382383
args['parallel'] === '' ||
383-
// dont require passing --parallel if NX_PARALLEL is set, but allow overriding it
384+
// don't require passing --parallel if NX_PARALLEL is set, but allow overriding it
384385
(process.env.NX_PARALLEL && args['parallel'] === undefined)
385386
) {
386-
return Number(
387+
return concurrency(
387388
args['maxParallel'] ||
388389
args['max-parallel'] ||
389390
process.env.NX_PARALLEL ||
390-
3
391+
'3'
391392
);
392393
} else if (args['parallel'] !== undefined) {
393-
return Number(args['parallel']);
394+
return concurrency(args['parallel']);
394395
}
395396
}
396397

@@ -407,3 +408,13 @@ const coerceTuiAutoExit = (value: string) => {
407408
}
408409
throw new Error(`Invalid value for --tui-auto-exit: ${value}`);
409410
};
411+
412+
function concurrency(val: string | number) {
413+
let parallel = typeof val === 'number' ? val : parseInt(val);
414+
415+
if (typeof val === 'string' && val.at(-1) === '%') {
416+
const maxCores = availableParallelism?.() ?? cpus().length;
417+
parallel = (maxCores * parallel) / 100;
418+
}
419+
return Math.max(1, Math.floor(parallel));
420+
}

0 commit comments

Comments
 (0)