123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- // NOTE:
- // - requires the env vars HTTP_PORT and AUTH_TOKENS (at least 1 token to bypass rate limiting) to be set
- // - requires geniURL to run in a different process (or using the command pnpm run latency-test)
- //
- // - requests are sent sequentially on purpose to avoid rate limiting on genius.com's side
- import "dotenv/config";
- import _axios from "axios";
- import percentile from "percentile";
- import k from "kleur";
- import type { Stringifiable } from "svcorelib";
- import queries from "./latency-test-queries.json" with { type: "json" };
- const settings = {
- /** Amount of requests to send in total. */
- amount: 10,
- /** Base URL to send requests to. `{{QUERY}}` will be replaced with a random query from the `latency-test-queries.json` file. */
- url: `http://127.0.0.1:${process.env.HTTP_PORT ?? 8074}/v2/search/top?q={{QUERY}}`,
- /** Whether to log all requests to the console. */
- logRequests: true,
- };
- const axios = _axios.create({ timeout: 20_000 });
- async function run() {
- console.log(`\n\n>>> Running latency test with ${settings.amount} requests...\n`);
- const startTs = Date.now();
- const times = [] as number[];
- for(let i = 0; i < settings.amount; i++) {
- i === 0 && console.log(`> Sent 0 of ${settings.amount} requests`);
- const start = Date.now();
- try {
- const url = settings.url.replace("{{QUERY}}", queries[Math.floor(Math.random() * queries.length)]);
- settings.logRequests && console.log(" *", url);
- await axios.get(url, {
- headers: {
- "Cache-Control": "no-cache",
- Authorization: `Bearer ${process.env.AUTH_TOKENS!.split(",")[0]}`,
- },
- });
- }
- catch(e) {
- console.error("Failed to send request:", e);
- }
- finally {
- times.push(Date.now() - start);
- i % 10 === 0 && i !== 0 && console.log(`> Sent ${i} of ${settings.amount} requests`);
- }
- }
- const min = times.reduce((a, c) => Math.min(a, c), Infinity).toFixed(0);
- const avg = (times.reduce((a, c) => a + c, 0) / times.length).toFixed(0);
- const max = times.reduce((a, c) => Math.max(a, c), 0).toFixed(0);
- const getPerc = (perc: number, times: number[]) => {
- const res = percentile(perc, times);
- if(Array.isArray(res)) return res[0];
- return res;
- };
- const logVal = (label: string, value: Stringifiable, kleurFunc?: (str: string) => void) => {
- const valStr = `${label}:\t${String(value).padStart(4, " ")} ms`;
- console.log(kleurFunc ? kleurFunc(valStr) : valStr);
- }
- console.log(`\n>>> Latency test finished sending all ${settings.amount} requests after ${((Date.now() - startTs) / 1000).toFixed(2)}s - Results:`);
- console.log();
- logVal("5th%", getPerc(5, times), k.gray);
- logVal("10th%", getPerc(10, times), k.gray);
- logVal("25th%", getPerc(25, times), k.gray);
- logVal("80th%", getPerc(80, times));
- logVal("90th%", getPerc(90, times));
- logVal("95th%", getPerc(95, times));
- logVal("97th%", getPerc(97, times), k.bold);
- logVal("98th%", getPerc(98, times));
- logVal("99th%", getPerc(99, times));
- console.log();
- logVal("min", min);
- logVal("avg", avg, k.bold);
- logVal("max", max);
- console.log();
- }
- run();
|