Show startup time in ready banner (#5799)

Integrated into release/v3.8.43
This commit is contained in:
Isha Tiwari
2026-07-02 06:31:54 +05:30
committed by GitHub
parent cc260c9459
commit a98b29e8be
2 changed files with 69 additions and 7 deletions

View File

@@ -63,6 +63,8 @@ export function registerServe(program) {
}
export async function runServe(opts = {}) {
const startedAt = performance.now();
const { isNativeBinaryCompatible } =
await import("../../../scripts/build/native-binary-compat.mjs");
const { getNodeRuntimeSupport, getNodeRuntimeWarning } =
@@ -191,7 +193,15 @@ export async function runServe(opts = {}) {
}
if (opts.noRecovery) {
return runWithoutRecovery(serverJs, env, memoryLimit, dashboardPort, apiPort, noOpen);
return runWithoutRecovery(
serverJs,
env,
memoryLimit,
dashboardPort,
apiPort,
noOpen,
startedAt
);
}
return runWithSupervisor(
@@ -203,6 +213,7 @@ export async function runServe(opts = {}) {
noOpen,
opts.log === true,
opts.maxRestarts ?? 2,
startedAt,
useTray
);
}
@@ -223,7 +234,7 @@ function runDaemon(serverJs, env, memoryLimit, dashboardPort, apiPort) {
console.log(` \x1b[1mAPI Base:\x1b[0m ${urlScheme}://localhost:${apiPort}/v1`);
}
function runWithoutRecovery(serverJs, env, memoryLimit, dashboardPort, apiPort, noOpen) {
function runWithoutRecovery(serverJs, env, memoryLimit, dashboardPort, apiPort, noOpen, startedAt) {
// #5238: skip the explicit CLI --max-old-space-size when the user pinned the
// heap via NODE_OPTIONS (a CLI arg would shadow/override their value).
const server = spawn("node", [...buildNodeHeapArgs(process.env, memoryLimit), serverJs], {
@@ -244,7 +255,7 @@ function runWithoutRecovery(serverJs, env, memoryLimit, dashboardPort, apiPort,
(text.includes("Ready") || text.includes("started") || text.includes("listening"))
) {
started = true;
onReady(dashboardPort, apiPort, noOpen);
onReady(dashboardPort, apiPort, noOpen, startedAt);
}
});
@@ -278,7 +289,7 @@ function runWithoutRecovery(serverJs, env, memoryLimit, dashboardPort, apiPort,
setTimeout(() => {
if (!started) {
started = true;
onReady(dashboardPort, apiPort, noOpen);
onReady(dashboardPort, apiPort, noOpen, startedAt);
}
}, 15000);
}
@@ -292,6 +303,7 @@ async function runWithSupervisor(
noOpen,
showLog,
maxRestarts,
startedAt,
useTray = false
) {
if (showLog) process.env.OMNIROUTE_SHOW_LOG = "1";
@@ -329,7 +341,7 @@ async function runWithSupervisor(
waitForServer(dashboardPort, 60000).then(async (up) => {
if (up) {
if (useTray) await maybeStartTray(dashboardPort, apiPort, supervisor);
onReady(dashboardPort, apiPort, noOpen);
onReady(dashboardPort, apiPort, noOpen, startedAt);
}
});
}
@@ -374,12 +386,16 @@ async function maybeStartTray(port, apiPort, supervisor) {
}
}
async function onReady(dashboardPort, apiPort, noOpen) {
async function onReady(dashboardPort, apiPort, noOpen, startedAt) {
const dashboardUrl = `${urlScheme}://localhost:${dashboardPort}`;
const apiUrl = `${urlScheme}://localhost:${apiPort}`;
const elapsed =
typeof startedAt === "number" && Number.isFinite(startedAt)
? ((performance.now() - startedAt) / 1000).toFixed(1)
: "0.0";
console.log(`
\x1b[32m✔ OmniRoute is running!\x1b[0m
\x1b[32m✔ OmniRoute is running!\x1b[0m \x1b[2m(started in ${elapsed}s)\x1b[0m
\x1b[1m Dashboard:\x1b[0m ${dashboardUrl}
\x1b[1m API Base:\x1b[0m ${apiUrl}/v1

View File

@@ -0,0 +1,46 @@
import test from "node:test";
import assert from "node:assert/strict";
const fs = await import("node:fs");
const path = await import("node:path");
const servePath = path.resolve(import.meta.dirname, "../../bin/cli/commands/serve.mjs");
const serveSource = fs.readFileSync(servePath, "utf-8");
test("serve startup time uses monotonic performance.now()", () => {
assert.match(serveSource, /performance\.now\(\)/);
assert.match(serveSource, /typeof startedAt === "number"/);
});
test("serve startup banner includes started in elapsed time", () => {
assert.match(serveSource, /started in/);
});
test("serve daemon mode does not accept startedAt", () => {
assert.match(
serveSource,
/function\s+runDaemon\s*\(\s*serverJs\s*,\s*env\s*,\s*memoryLimit\s*,\s*dashboardPort\s*,\s*apiPort\s*\)/
);
assert.ok(
!/function\s+runDaemon\s*\(\s*serverJs\s*,\s*env\s*,\s*memoryLimit\s*,\s*dashboardPort\s*,\s*apiPort\s*,\s*startedAt\s*\)/.test(
serveSource
)
);
});
test("serve runWithSupervisor uses startedAt before defaulted useTray", () => {
const signatureRegex =
/async\s+function\s+runWithSupervisor\s*\([\s\S]*?startedAt\s*,\s*useTray\s*=\s*false\s*\)/;
assert.match(
serveSource,
signatureRegex,
"runWithSupervisor should declare startedAt before the defaulted useTray parameter"
);
const callRegex = /runWithSupervisor\s*\([\s\S]*?startedAt\s*,\s*useTray\s*\)/;
assert.match(
serveSource,
callRegex,
"runWithSupervisor should be called with startedAt before useTray"
);
});