Skip to content

Commit

Permalink
default to no multithreading with less than 4 CPUs
Browse files Browse the repository at this point in the history
  • Loading branch information
fasttime committed Nov 23, 2024
1 parent cc6a8af commit 4030f70
Show file tree
Hide file tree
Showing 5 changed files with 300 additions and 255 deletions.
4 changes: 1 addition & 3 deletions lib/create-cli-execute.js
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,8 @@ export default async function createCLIExecute(eslintDirURL, calculateInspectCon
const engine = await ESLint.fromCLIOptions(options);
if (useStdin)
results = await engine.lintText(text, { filePath: options.stdinFilename });
else if (options.concurrency === 'off')
results = await engine.lintFiles(files);
else
results = await engine.lintParallel(files);
results = await engine.lintFiles(files);
if (options.fix)
{
debug('Fix mode enabled - applying fixes');
Expand Down
53 changes: 38 additions & 15 deletions lib/patch-eslint.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,21 @@ import limitConcurrency from './limit-concurrency.js';

function calculateMaxConcurrency(concurrency)
{
const maxConcurrency =
typeof concurrency === 'number' && concurrency >= 1 ?
Math.floor(concurrency) : Math.max(availableParallelism() >> 1, 1);
let maxConcurrency;
switch (concurrency)
{
case 'off':
maxConcurrency = 0;
break;
case undefined:
case 'auto':
maxConcurrency = availableParallelism() >> 1;
if (maxConcurrency < 2) maxConcurrency = 0;
break;
default:
maxConcurrency = Math.floor(concurrency);
break;
}
return maxConcurrency;
}

Expand All @@ -42,6 +54,9 @@ async function loadConfigArraysForFiles(filePaths, configLoader, maxConcurrency,

export default async function patchESLint(eslintDirURL, ESLint)
{
const { prototype } = ESLint;
if (createVerifyTextModuleURLKey in prototype) return;

/** @type {WeakMap<ESLint, Record<string, unknown>>} */
const privateMembers = grabPrivateMembers(ESLint);

Expand Down Expand Up @@ -79,15 +94,19 @@ export default async function patchESLint(eslintDirURL, ESLint)
return engine;
}

// lintParallel ////////////////////////////////////////////////////////////////////////////////
// lintFiles ///////////////////////////////////////////////////////////////////////////////////

/**
* Executes the current configuration on an array of file and directory names in parallel.
* @param {string|string[]} patterns An array of file and directory names.
* Executes the current configuration on an array of file names in parallel.
* @param {string|string[]} patterns An array of file names.
* @returns {Promise<LintResult[]>} The results of linting the file patterns given.
*/
async function lintParallel(patterns)
async function lintFiles(patterns)
{
const engineInfo = engineInfoMap.get(this);
const { maxConcurrency } = engineInfo;
if (!maxConcurrency)
return await originalLintFiles.call(this, patterns);
let normalizedPatterns = patterns;
const { cacheFilePath, configLoader, lintResultCache, options: eslintOptions } =
privateMembers.get(this);
Expand Down Expand Up @@ -152,16 +171,14 @@ export default async function patchESLint(eslintDirURL, ESLint)
},
);
debug(`${filePaths.length} files found in: ${Date.now() - startTime}ms`);
const engineInfo = engineInfoMap.get(this);
const abortController = new AbortController();
const [results] =
await Promise.all
(
[
runWorkers
(filePaths, engineInfo, this[createVerifyTextModuleURLKey], abortController),
loadConfigArraysForFiles
(filePaths, configLoader, engineInfo.maxConcurrency, abortController),
loadConfigArraysForFiles(filePaths, configLoader, maxConcurrency, abortController),
],
);
// Persist the cache to disk.
Expand Down Expand Up @@ -193,6 +210,13 @@ export default async function patchESLint(eslintDirURL, ESLint)
return processLintReport(this, { results: finalResults });
}

/**
* @param {string[]} filePaths
* @param {{ cliOptions: ParsedCLIOptions, maxConcurrency: number }} engineInfo
* @param {string} createVerifyTextModuleURL
* @param {AbortController} abortController
* @returns {Promise<ESLint.LintResult[]>}
*/
async function runWorkers
(filePaths, { cliOptions, maxConcurrency }, createVerifyTextModuleURL, abortController)
{
Expand Down Expand Up @@ -251,14 +275,13 @@ export default async function patchESLint(eslintDirURL, ESLint)
return results;
}

const originalLintFiles = prototype.lintFiles;

// Patch ///////////////////////////////////////////////////////////////////////////////////////

ESLint.fromCLIOptions = fromCLIOptions;
{
const { prototype } = ESLint;
prototype.lintParallel = lintParallel;
prototype[createVerifyTextModuleURLKey] = '#create-verify-text';
}
prototype.lintFiles = lintFiles;
prototype[createVerifyTextModuleURLKey] = '#create-verify-text';
}

export const createVerifyTextModuleURLKey = Symbol();
28 changes: 12 additions & 16 deletions test/cli-execute.js
Original file line number Diff line number Diff line change
Expand Up @@ -1456,7 +1456,7 @@ describe
.expects('fromCLIOptions')
.withExactArgs(sinon.match({ inlineConfig: false }))
.callThrough();
sinon.stub(ESLint.prototype, 'lintParallel').returns
sinon.stub(ESLint.prototype, 'lintFiles').returns
(
[
{
Expand Down Expand Up @@ -1493,7 +1493,7 @@ describe
.expects('fromCLIOptions')
.withExactArgs(sinon.match({ inlineConfig: true }))
.callThrough();
sinon.stub(ESLint.prototype, 'lintParallel').returns([]);
sinon.stub(ESLint.prototype, 'lintFiles').returns([]);
sinon
.stub(ESLint.prototype, 'loadFormatter')
.returns({ format: () => 'done' });
Expand Down Expand Up @@ -1524,7 +1524,7 @@ describe
.expects('fromCLIOptions')
.withExactArgs(sinon.match({ fix: true }))
.callThrough();
sinon.stub(ESLint.prototype, 'lintParallel').returns([]);
sinon.stub(ESLint.prototype, 'lintFiles').returns([]);
sinon
.stub(ESLint.prototype, 'loadFormatter')
.returns({ format: () => 'done' });
Expand Down Expand Up @@ -1561,7 +1561,7 @@ describe
.expects('fromCLIOptions')
.withExactArgs(sinon.match({ fix: true }))
.callThrough();
sinon.stub(ESLint.prototype, 'lintParallel').returns(report);
sinon.stub(ESLint.prototype, 'lintFiles').returns(report);
sinon
.stub(ESLint.prototype, 'loadFormatter')
.returns({ format: () => 'done' });
Expand Down Expand Up @@ -1599,7 +1599,7 @@ describe
.expects('fromCLIOptions')
.withExactArgs(sinon.match({ fix: true, quiet: true }))
.callThrough();
sinon.stub(ESLint.prototype, 'lintParallel').returns(report);
sinon.stub(ESLint.prototype, 'lintFiles').returns(report);
sinon
.stub(ESLint.prototype, 'loadFormatter')
.returns({ format: () => 'done' });
Expand Down Expand Up @@ -1647,7 +1647,7 @@ describe
.expects('fromCLIOptions')
.withExactArgs(sinon.match({ fixDryRun: true }))
.callThrough();
sinon.stub(ESLint.prototype, 'lintParallel').returns([]);
sinon.stub(ESLint.prototype, 'lintFiles').returns([]);
sinon
.stub(ESLint.prototype, 'loadFormatter')
.returns({ format: () => 'done' });
Expand All @@ -1673,7 +1673,7 @@ describe
.expects('fromCLIOptions')
.withExactArgs(sinon.match(expectedESLintOptions))
.callThrough();
sinon.stub(ESLint.prototype, 'lintParallel').returns([]);
sinon.stub(ESLint.prototype, 'lintFiles').returns([]);
sinon
.stub(ESLint.prototype, 'loadFormatter')
.returns({ format: () => 'done' });
Expand Down Expand Up @@ -1710,7 +1710,7 @@ describe
.expects('fromCLIOptions')
.withExactArgs(sinon.match({ fixDryRun: true }))
.callThrough();
sinon.stub(ESLint.prototype, 'lintParallel').returns(report);
sinon.stub(ESLint.prototype, 'lintFiles').returns(report);
sinon
.stub(ESLint.prototype, 'loadFormatter')
.returns({ format: () => 'done' });
Expand Down Expand Up @@ -1747,7 +1747,7 @@ describe
.expects('fromCLIOptions')
.withExactArgs(sinon.match({ fixDryRun: true, quiet: true }))
.callThrough();
sinon.stub(ESLint.prototype, 'lintParallel').returns(report);
sinon.stub(ESLint.prototype, 'lintFiles').returns(report);
sinon
.stub(ESLint.prototype, 'loadFormatter')
.returns({ format: () => 'done' });
Expand Down Expand Up @@ -1785,7 +1785,7 @@ describe
.expects('fromCLIOptions')
.withExactArgs(sinon.match({ fixDryRun: true }))
.callThrough();
sinon.stub(ESLint.prototype, 'lintParallel').returns(report);
sinon.stub(ESLint.prototype, 'lintFiles').returns(report);
sinon
.stub(ESLint.prototype, 'loadFormatter')
.returns({ format: () => 'done' });
Expand Down Expand Up @@ -2420,11 +2420,8 @@ describe
'`--concurrency=auto`',
async () =>
{
sinon.spy(ESLint.prototype, 'lintFiles');
const exitCode = await execute('--concurrency=auto passing.js');

assert(log.error.notCalled);
assert(ESLint.prototype.lintFiles.notCalled);
assert.equal(exitCode, 0);
},
);
Expand All @@ -2434,12 +2431,11 @@ describe
'`--concurrency=off`',
async () =>
{
sinon.spy(ESLint.prototype, 'lintFiles');
sinon.spy(globalThis, 'SharedArrayBuffer');
const exitCode = await execute('--concurrency=off passing.js');

assert(log.error.notCalled);
assert(ESLint.prototype.lintFiles.called);
assert.equal(exitCode, 0);
assert(SharedArrayBuffer.notCalled);
},
);

Expand Down
Loading

0 comments on commit 4030f70

Please sign in to comment.