mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-01 12:52:11 +03:00
Show startup time in ready banner (#5799)
Integrated into release/v3.8.43
This commit is contained in:
@@ -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
|
||||
|
||||
46
tests/unit/cli-serve-startup-time.test.ts
Normal file
46
tests/unit/cli-serve-startup-time.test.ts
Normal 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"
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user