Explorar o código

ref: improve latency test

Sv443 hai 4 meses
pai
achega
2d72989bc3
Modificáronse 3 ficheiros con 204 adicións e 23 borrados
  1. 3 1
      package.json
  2. 150 0
      src/dev/latency-test-queries.json
  3. 51 22
      src/dev/latency-test.ts

+ 3 - 1
package.json

@@ -11,8 +11,10 @@
     "build-www": "cd www && pnpm run build",
     "dev-all": "concurrently \"pnpm dev\" \"pnpm dev-www\"",
     "lint": "eslint . && tsc --noEmit",
+    "run-unit-tests": "jest --testLocationInResults --verbose",
+    "run-latency-test": "tsx src/dev/latency-test.ts",
     "test": "start-server-and-test start http://127.0.0.1:8074/v2/health run-tests",
-    "run-tests": "jest --testLocationInResults --verbose"
+    "latency-test": "start-server-and-test start http://127.0.0.1:8074/v2/health run-latency-test"
   },
   "repository": {
     "type": "git",

+ 150 - 0
src/dev/latency-test-queries.json

@@ -0,0 +1,150 @@
+[
+  "SOPHIE - BIPP",
+  "SOPHIE - ELLE",
+  "SOPHIE - LEMONADE",
+  "SOPHIE - HARD",
+  "SOPHIE - MSMSMSM",
+  "SOPHIE - VYZEE",
+  "SOPHIE - L.O.V.E.",
+  "SOPHIE - JUST LIKE WE NEVER SAID GOODBYE",
+  "SOPHIE - GET HIGHER",
+  "SOPHIE - Intro (The Full Horror)",
+  "SOPHIE - Rawwwwww",
+  "SOPHIE - Plunging Asymptote",
+  "SOPHIE - The Dome's Protection",
+  "SOPHIE - Reason Why",
+  "SOPHIE - Live In My Truth",
+  "SOPHIE - Why Lies",
+  "SOPHIE - Do You Wanna Be Alive",
+  "SOPHIE - Elegance",
+  "SOPHIE - Berlin Nightmare",
+  "SOPHIE - Gallop",
+  "SOPHIE - One More Time",
+  "SOPHIE - Exhilarate",
+  "SOPHIE - Always and Forever",
+  "SOPHIE - My Forever",
+  "SOPHIE - Love Me Off Earth",
+  "SOPHIE - Ponyboy",
+  "SOPHIE - Faceshopping",
+  "SOPHIE - It's Okay To Cry",
+  "flume highest building",
+  "flume say nothing",
+  "flume dhlc",
+  "flume escape",
+  "flume i cant tell",
+  "flume get u",
+  "flume jaspers song",
+  "flume only fans",
+  "flume hollow",
+  "flume love light",
+  "flume sirens",
+  "flume go",
+  "flume palaces",
+  "flume miss u",
+  "flume - hi this is flume",
+  "flume - ecdysis",
+  "flume & hwls - high beams (ft. slowthai)",
+  "flume - jewel",
+  "flume - dreamtime",
+  "flume & sophie - is it cold in the water? (flume & eprom remix)",
+  "flume - how to build a relationship (ft. jpegmafia)",
+  "flume - wormhole",
+  "flume - voices (ft. kučka & sophie)",
+  "flume - mud",
+  "flume - upgrade",
+  "flume - 71m3",
+  "flume - vitality",
+  "flume - daze 22.00",
+  "flume - amber",
+  "flume & eprom - spring",
+  "Apashe - Overture",
+  "Apashe - Distance (ft. Geoffroy)",
+  "Apashe - Behind My Eyes (ft. Lia Kurihara)",
+  "Apashe - Lord & Master",
+  "Apashe - Dead (ft. Yizzy)",
+  "Apashe & Instasamka - Uebok (Gotta Run)",
+  "Apashe - Good News",
+  "Apashe - Insane (ft. Tech N9ne)",
+  "Apashe - Work (ft. Vo Williams)",
+  "Apashe & High Klassified - I'm Fine (ft. Cherry Lena)",
+  "Apashe & Slumberjack - Legend (ft. Wasiu)",
+  "Apashe - Green Crack (ft. wifisfuneral)",
+  "Apashe - Rain (ft. KROY)",
+  "apashe - king (ft. busta rhymes)",
+  "apashe - catch me",
+  "apashe & sofiane pamart - devil may cry",
+  "apashe & wasiu - human",
+  "apashe - revenge of the orchestra (ft. magugu)",
+  "apashe & flux pavillion - fracture (ft. joey valence & brae)",
+  "apashe - kryptonite (ft. lia kurihara)",
+  "apashe - rise at nightfall (ft. rhita nattah)",
+  "apashe & raga - gasoline",
+  "apashe & geoffroy - lost in mumbai",
+  "apashe & high klassified - menace (ft. earthgang)",
+  "apashe & ymir - contraband",
+  "apashe & vladimir cauchemar - rip",
+  "DROELOE SPARK",
+  "DROELOE Foolish Fish",
+  "DROELOE Strange Wave",
+  "DROELOE Landscape (ft. BANJI)",
+  "DROELOE Mundane Av.",
+  "DROELOE Kicking Gates",
+  "DROELOE A Current, A Void",
+  "DROELOE Feeble Games",
+  "DROELOE Lion Heart (ft. Lisa van Nes)",
+  "DROELOE Hermit (ft. Emilia Ali)",
+  "DROELOE The Wheel",
+  "DROELOE Decision",
+  "DROELOE Downside Up (ft. Transviolet)",
+  "DROELOE Terminal Velocity",
+  "DROELOE Counting Ten",
+  "Tyler The Creator St. Chroma (ft. Daniel Caesar)",
+  "Tyler The Creator Rah Tah Tah",
+  "Tyler The Creator Noid",
+  "Tyler The Creator Darling, I (ft. Teezo Touchdown)",
+  "Tyler The Creator Hey Jane",
+  "Tyler The Creator I Killed You",
+  "Tyler The Creator Judge Judy",
+  "Tyler The Creator Sticky (ft. GloRilla, Lil Wayne & Sexyy Red)",
+  "Tyler The Creator Take Your Mask Off (ft. Daniel Caesar & LaToiya Williams)",
+  "Tyler The Creator Tomorrow",
+  "Tyler The Creator Thought I Was Dead (ft. Santigold & ScHoolboy Q)",
+  "Tyler The Creator Like Him (ft. Lola Young)",
+  "Tyler The Creator Balloon (ft. Doechii)",
+  "Tyler The Creator I Hope You Find Your Way Home",
+  "pink guy hot nickel ball on a pussy",
+  "pink guy are you serious",
+  "pink guy white is right",
+  "pink guy i have a gun",
+  "pink guy nickelodeon girls",
+  "pink guy stfu",
+  "pink guy gays 4 donald trump",
+  "pink guy i do it for my hood",
+  "pink guy please stop calling me gay",
+  "pink guy she's so nice",
+  "pink guy please stop touching my willy",
+  "pink guy uber pussy",
+  "pink guy セックス大好き",
+  "pink guy dumplings by pinkomega",
+  "pink guy meme machine",
+  "pink guy hand on my gat",
+  "pink guy d i c c w e t t 1",
+  "pink guy flex like david icke",
+  "pink guy high school blink193",
+  "pink guy rice balls",
+  "pink guy dora the explora",
+  "pink guy smd",
+  "pink guy dog festival directions",
+  "pink guy we fall again",
+  "pink guy club banger 3000",
+  "pink guy help",
+  "pink guy hentai",
+  "pink guy small dick",
+  "pink guy pink life",
+  "pink guy another earth",
+  "pink guy i will get a vasectomy",
+  "pink guy furr",
+  "pink guy fried noodles",
+  "pink guy goofy's trial",
+  "pink guy be inspired"
+]

+ 51 - 22
src/dev/latency-test.ts

@@ -1,13 +1,21 @@
 // NOTE:
-// requires the env vars HTTP_PORT and AUTH_TOKENS to be set
+// - 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)
 
 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: 100,
-  url: `http://127.0.0.1:${process.env.HTTP_PORT}/search/top?q=pink guy - dog festival directions`,
+  /** 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}/v2/search/top?q={{QUERY}}`,
+  /** Whether to log all requests to the console. */
+  logRequests: true,
 };
 
 
@@ -19,34 +27,55 @@ async function run() {
 
   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();
-    await axios.get(settings.url, {
-      headers: {
-        "Cache-Control": "no-cache",
-        Authorization: `Bearer ${process.env.AUTH_TOKENS!.split(",")[0]}`,
-      },
-    });
-    times.push(Date.now() - start);
-
-    i % 10 === 0 && i !== 0 && console.log(`Sent ${i} of ${settings.amount} requests`);
+    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 perc80 = percentile(80, times);
-  const perc90 = percentile(90, times);
-  const perc95 = percentile(95, times);
-  const perc99 = percentile(99, times);
 
-  console.log(`\n>>> Latency test finished after ${((Date.now() - startTs) / 1000).toFixed(2)}s`);
+  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();
-  console.log(`avg:\t${avg}\tms`);
-  console.log(`max:\t${max}\tms`);
+  logVal("min", min);
+  logVal("avg", avg, k.bold);
+  logVal("max", max);
   console.log();
-  console.log(`80th%:\t${perc80}\tms`);
-  console.log(`90th%:\t${perc90}\tms`);
-  console.log(`95th%:\t${perc95}\tms`);
-  console.log(`99th%:\t${perc99}\tms`);
+  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();
 }