Public: anyone can read this; the crew can change it.
Sentinel: shared:01m23vygyffx5hg2f5vm8r74sr:6ryojgfus8 was degraded 69 minutes today: trevato/forge: "the proxy adds under 5 ms (median) and 20 ms (p95) with the toolbar rewrite" failed on 3 pulls in the l… #9198
Check · Review · Land · Live done — Landed and live in production.
mason/forge:mason/9187-sentinel-shared-01m23vygyffx5hg2f5vm8r74 → main 2 commits fork
1 file
changed +18
−4
test/apps-proxy-overhead.test.ts +18 −4
| @@ -7,7 +7,7 @@ | ||
| 7 | 7 | |
| 8 | 8 | import { afterAll, beforeAll, spyOn, test } from "bun:test"; |
| 9 | 9 | import { mkdtemp, rm } from "node:fs/promises"; |
| 10 | import { tmpdir } from "node:os"; | |
| 10 | import { loadavg, tmpdir } from "node:os"; | |
| 11 | 11 | import { join } from "node:path"; |
| 12 | 12 | import { createApp, type App } from "../src/app.ts"; |
| 13 | 13 | import { newApp } from "../src/actions/apps.ts"; |
| @@ -24,7 +24,13 @@ const DOMAIN = "apps.test"; | ||
| 24 | 24 | const RUNS = 25; |
| 25 | 25 | const MEDIAN_MS = 5; |
| 26 | 26 | const P95_MS = 20; |
| 27 | // Rounds are tried for at most this long (under the test's own timeout), and at | |
| 28 | // least ROUNDS of them: a loaded lane can stay slow for many seconds, a real | |
| 29 | // regression stays slow in every round. | |
| 27 | 30 | const ROUNDS = 20; |
| 31 | const WINDOW_MS = 10_000; | |
| 32 | // One in-flight round and slowest() fit after the window, so the budget message wins. | |
| 33 | const TIMEOUT_MS = WINDOW_MS + 15_000; | |
| 28 | 34 | // About the size of the scaffold app's home page. |
| 29 | 35 | const PAGE = `<!doctype html><html><head><title>notes</title></head><body>${"<p>hello hello hello</p>".repeat(60)}</body></html>`; |
| 30 | 36 | |
| @@ -140,21 +146,29 @@ for (const [label, pill] of [["with the toolbar rewrite", undefined], ["without | ||
| 140 | 146 | // every round and fails; a noisy round cannot. |
| 141 | 147 | let median = Infinity; |
| 142 | 148 | let p95 = Infinity; |
| 143 | for (let round = 0; round < ROUNDS; round++) { | |
| 149 | let directMedian = Infinity; | |
| 150 | const began = performance.now(); | |
| 151 | let rounds = 0; | |
| 152 | while (rounds < ROUNDS || performance.now() - began < WINDOW_MS) { | |
| 153 | rounds++; | |
| 144 | 154 | const overhead: number[] = []; |
| 155 | const directs: number[] = []; | |
| 145 | 156 | for (let i = 0; i < RUNS; i++) { |
| 146 | 157 | // Back to back, so a slow moment on the machine lands on both. |
| 147 | 158 | const d = await time(direct, { accept: "text/html" }); |
| 148 | 159 | const p = await time(proxied, HEADERS); |
| 149 | 160 | overhead.push(p - d); |
| 161 | directs.push(d); | |
| 150 | 162 | } |
| 151 | 163 | overhead.sort((x, y) => x - y); |
| 164 | directs.sort((x, y) => x - y); | |
| 165 | directMedian = Math.min(directMedian, at(directs, 0.5)); | |
| 152 | 166 | median = Math.min(median, at(overhead, 0.5)); |
| 153 | 167 | p95 = Math.min(p95, at(overhead, 0.95)); |
| 154 | 168 | if (median < MEDIAN_MS && p95 < P95_MS) return; |
| 155 | 169 | } |
| 156 | 170 | throw new Error( |
| 157 | `proxy overhead floor: median ${median.toFixed(2)} ms (budget ${MEDIAN_MS}), p95 ${p95.toFixed(2)} ms (budget ${P95_MS}) over ${ROUNDS} rounds; five slowest phases: ${await slowest()}`, | |
| 171 | `proxy overhead floor: median ${median.toFixed(2)} ms (budget ${MEDIAN_MS}), p95 ${p95.toFixed(2)} ms (budget ${P95_MS}) over ${rounds} rounds (direct fetch median floor ${directMedian.toFixed(2)} ms, load average ${loadavg().map((l) => l.toFixed(1)).join(" ")}; a high direct floor means a loaded machine, a low one means the proxy); five slowest phases: ${await slowest()}`, | |
| 158 | 172 | ); |
| 159 | }, 60_000); | |
| 173 | }, TIMEOUT_MS); | |
| 160 | 174 | } |
new above
offline