Skip to content

Commit b78207d

Browse files
authored
feat(loader-runner): Allow limiting worker pool size for parallel loaders (#12277)
* feat(loader-runner): Make tinypool thread count configurable * Addressing comments
1 parent c27ad4c commit b78207d

File tree

9 files changed

+58
-10
lines changed

9 files changed

+58
-10
lines changed

packages/rspack/etc/core.api.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4510,7 +4510,9 @@ class LoaderObject {
45104510
// (undocumented)
45114511
options?: string | object;
45124512
// (undocumented)
4513-
parallel?: boolean;
4513+
parallel?: boolean | {
4514+
maxWorkers?: number;
4515+
};
45144516
// (undocumented)
45154517
path: string;
45164518
// (undocumented)
@@ -7049,7 +7051,9 @@ export type RuleSetLoaderOptions = string | Record<string, any>;
70497051
export type RuleSetLoaderWithOptions = {
70507052
ident?: string;
70517053
loader: RuleSetLoader;
7052-
parallel?: boolean;
7054+
parallel?: boolean | {
7055+
maxWorkers?: number;
7056+
};
70537057
options?: RuleSetLoaderOptions;
70547058
};
70557059

packages/rspack/src/config/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ export type RuleSetLoaderWithOptions = {
882882

883883
loader: RuleSetLoader;
884884

885-
parallel?: boolean;
885+
parallel?: boolean | { maxWorkers?: number };
886886

887887
options?: RuleSetLoaderOptions;
888888
};

packages/rspack/src/loader-runner/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ export class LoaderObject {
144144
pitch?: Function;
145145
raw?: boolean;
146146
type?: "module" | "commonjs";
147-
parallel?: boolean;
147+
parallel?: boolean | { maxWorkers?: number };
148148
/**
149149
* @internal This field is rspack internal. Do not edit.
150150
*/
@@ -995,7 +995,10 @@ export async function runLoaders(
995995
loaderState,
996996
args
997997
},
998-
getWorkerLoaderHandlers()
998+
getWorkerLoaderHandlers(),
999+
typeof currentLoaderObject?.parallel === "object"
1000+
? currentLoaderObject.parallel
1001+
: undefined
9991002
)) || [];
10001003
} else {
10011004
if (loaderState === JsLoaderState.Normal)

packages/rspack/src/loader-runner/service.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,25 @@ import path from "node:path";
33
import type { Tinypool } from "tinypool" with { "resolution-mode": "import" };
44

55
let pool: Promise<Tinypool> | undefined;
6-
const ensureLoaderWorkerPool = async () => {
6+
const ensureLoaderWorkerPool = async (workerOptions?: {
7+
maxWorkers?: number;
8+
}) => {
79
if (pool) {
810
return pool;
911
}
1012
return (pool = import("tinypool").then(({ Tinypool }) => {
1113
const cpus = require("node:os").cpus().length;
1214
const availableThreads = Math.max(cpus - 1, 1);
15+
const maxWorkers = workerOptions?.maxWorkers
16+
? Math.max(workerOptions.maxWorkers, 1)
17+
: undefined;
1318

1419
const pool = new Tinypool({
1520
filename: path.resolve(__dirname, "worker.js"),
1621
useAtomics: false,
1722

18-
maxThreads: availableThreads,
19-
minThreads: availableThreads,
23+
maxThreads: maxWorkers || availableThreads,
24+
minThreads: maxWorkers || availableThreads,
2025
concurrentTasksPerWorker: 1
2126
});
2227

@@ -199,9 +204,10 @@ export const run = async (
199204
task: any,
200205
options: RunOptions & {
201206
handleIncomingRequest: HandleIncomingRequest;
202-
}
207+
},
208+
workerOptions?: { maxWorkers?: number }
203209
) =>
204-
ensureLoaderWorkerPool().then(async pool => {
210+
ensureLoaderWorkerPool(workerOptions).then(async pool => {
205211
const { MessageChannel } = await import("node:worker_threads");
206212
const { port1: mainPort, port2: workerPort } = new MessageChannel();
207213
// Create message channel for processing sync API requests from worker
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
it("should run loader in parallel", () => {
2+
expect(require("./lib.js")).toBe(true)
3+
})

tests/rspack-test/configCases/loader-parallel/parallel-object/lib.js

Whitespace-only changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = function () {
2+
return `module.exports = ${this.parallel}`;
3+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module.exports = {
2+
context: __dirname,
3+
module: {
4+
rules: [
5+
{
6+
test: /lib\.js/,
7+
use: [
8+
{
9+
loader: "./unclonable.js",
10+
options: {
11+
notclonable() {}
12+
}
13+
},
14+
{
15+
loader: "./loader-in-worker.js",
16+
parallel: { maxWorkers: 2 },
17+
options: {}
18+
}
19+
]
20+
}
21+
]
22+
},
23+
experiments: {
24+
parallelLoader: true
25+
}
26+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = function(content) {
2+
return content
3+
}

0 commit comments

Comments
 (0)