mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 12:19:12 +00:00
feat(serve): Opt-in parallelism for deno serve
(#24920)
Adds a `parallel` flag to `deno serve`. When present, we spawn multiple workers to parallelize serving requests. ```bash deno serve --parallel main.ts ``` Currently on linux we use `SO_REUSEPORT` and rely on the fact that the kernel will distribute connections in a round-robin manner. On mac and windows, we sort of emulate this by cloning the underlying file descriptor and passing a handle to each worker. The connections will not be guaranteed to be fairly distributed (and in practice almost certainly won't be), but the distribution is still spread enough to provide a significant performance increase. --- (Run on an Macbook Pro with an M3 Max, serving `deno.com` baseline:: ``` ❯ wrk -d 30s -c 125 --latency http://127.0.0.1:8000 Running 30s test @ http://127.0.0.1:8000 2 threads and 125 connections Thread Stats Avg Stdev Max +/- Stdev Latency 239.78ms 13.56ms 330.54ms 79.12% Req/Sec 258.58 35.56 360.00 70.64% Latency Distribution 50% 236.72ms 75% 248.46ms 90% 256.84ms 99% 268.23ms 15458 requests in 30.02s, 2.47GB read Requests/sec: 514.89 Transfer/sec: 84.33MB ``` this PR (`with --parallel` flag) ``` ❯ wrk -d 30s -c 125 --latency http://127.0.0.1:8000 Running 30s test @ http://127.0.0.1:8000 2 threads and 125 connections Thread Stats Avg Stdev Max +/- Stdev Latency 117.40ms 142.84ms 590.45ms 79.07% Req/Sec 1.33k 175.19 1.77k 69.00% Latency Distribution 50% 22.34ms 75% 223.67ms 90% 357.32ms 99% 460.50ms 79636 requests in 30.07s, 12.74GB read Requests/sec: 2647.96 Transfer/sec: 433.71MB ```
This commit is contained in:
parent
875ee618d3
commit
e92a05b551
15 changed files with 617 additions and 141 deletions
|
@ -45,6 +45,7 @@ const {
|
|||
PromiseResolve,
|
||||
SafeSet,
|
||||
StringPrototypeIncludes,
|
||||
StringPrototypePadEnd,
|
||||
StringPrototypeSplit,
|
||||
StringPrototypeTrim,
|
||||
Symbol,
|
||||
|
@ -709,8 +710,37 @@ function bootstrapMainRuntime(runtimeOptions, warmup = false) {
|
|||
11: mode,
|
||||
12: servePort,
|
||||
13: serveHost,
|
||||
14: serveIsMain,
|
||||
15: serveWorkerCount,
|
||||
} = runtimeOptions;
|
||||
|
||||
if (mode === executionModes.serve) {
|
||||
if (serveIsMain && serveWorkerCount) {
|
||||
const origLog = console.log;
|
||||
const origError = console.error;
|
||||
const prefix = `[serve-worker-0 ]`;
|
||||
console.log = (...args) => {
|
||||
return origLog(prefix, ...new primordials.SafeArrayIterator(args));
|
||||
};
|
||||
console.error = (...args) => {
|
||||
return origError(prefix, ...new primordials.SafeArrayIterator(args));
|
||||
};
|
||||
} else if (serveWorkerCount !== null) {
|
||||
const origLog = console.log;
|
||||
const origError = console.error;
|
||||
const base = `serve-worker-${serveWorkerCount + 1}`;
|
||||
// 15 = "serve-worker-nn".length, assuming
|
||||
// serveWorkerCount < 100
|
||||
const prefix = `[${StringPrototypePadEnd(base, 15, " ")}]`;
|
||||
console.log = (...args) => {
|
||||
return origLog(prefix, ...new primordials.SafeArrayIterator(args));
|
||||
};
|
||||
console.error = (...args) => {
|
||||
return origError(prefix, ...new primordials.SafeArrayIterator(args));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (mode === executionModes.run || mode === executionModes.serve) {
|
||||
let serve = undefined;
|
||||
core.addMainModuleHandler((main) => {
|
||||
|
@ -725,13 +755,16 @@ function bootstrapMainRuntime(runtimeOptions, warmup = false) {
|
|||
}
|
||||
|
||||
if (mode === executionModes.serve && !serve) {
|
||||
console.error(
|
||||
`%cerror: %cdeno serve requires %cexport default { fetch }%c in the main module, did you mean to run \"deno run\"?`,
|
||||
"color: yellow;",
|
||||
"color: inherit;",
|
||||
"font-weight: bold;",
|
||||
"font-weight: normal;",
|
||||
);
|
||||
if (serveIsMain) {
|
||||
// Only error if main worker
|
||||
console.error(
|
||||
`%cerror: %cdeno serve requires %cexport default { fetch }%c in the main module, did you mean to run \"deno run\"?`,
|
||||
"color: yellow;",
|
||||
"color: inherit;",
|
||||
"font-weight: bold;",
|
||||
"font-weight: normal;",
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -746,7 +779,7 @@ function bootstrapMainRuntime(runtimeOptions, warmup = false) {
|
|||
);
|
||||
}
|
||||
if (mode === executionModes.serve) {
|
||||
serve({ servePort, serveHost });
|
||||
serve({ servePort, serveHost, serveIsMain, serveWorkerCount });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue