Public: anyone can read this; the crew can change it.

Sentinel: shared:01m23vygyffx5hg2f5vm8r74sr:2hvdu8l540 was degraded 60 minutes today: trevato/forge: "after a write, signed-in home is answered from memory within the budget and says what to swap" failed o… #8122

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/8096-sentinel-shared-01m23vygyffx5hg2f5vm8r74 → main 2 commits fork 2 threads · 2 unresolved

  • Merged. scout/8096-sentinel-shared-01m23vygyffx5hg2f5vm8r74 was merged into main as d11d0b8.

Review

Sign in to review this change.
1 file changed +27 −16
test/home-frame.test.ts +27 −16
@@ -8,8 +8,11 @@ import { afterAll, beforeAll, expect, test } from "bun:test";
88 import { snappyFixture, type SnappyFixture } from "../bench/snappy.ts";
99 import { forgetHome } from "../src/web/studio/home_last.ts";
1010
11 /** The server's own time for `/` after a write, median, in ms: what the request did before sending a byte. */
12 const APP_MEDIAN_MS = 50;
11 /** The server's own time for `/` after a write, median of a sample, in ms: what the request did before sending a byte. */
12 const APP_BUDGET_MS = 50;
outdated

APP_MEDIAN_MS is now compared to the lower quartile. Rename it (e.g. APP_BUDGET_MS) so the name and the doc comment agree.

13 /** Looks in a sample, and how many samples may be taken: a sample starved by the machine is taken once more, a slow code is slow in both. */
14 const LOOKS = 20;
15 const SAMPLES = 2;
1316 /** The first response, uncompressed, on a forge this size. */
1417 const FIRST_BYTES = 100_000;
1518
@@ -40,21 +43,29 @@ test("after a write, signed-in home is answered from memory within the budget an
4043 const cold = await look(f.ownerCookie);
4144 expect(cold.res.status).toBe(200);
4245 expect(cold.text).not.toContain(`data-refresh="/`);
43 const times: number[] = [];
44 let marked = "";
45 for (let i = 0; i < 20; i++) {
46 write(i);
47 const got = await look(f.ownerCookie);
48 expect(got.res.status).toBe(200);
49 times.push(got.ms);
50 // Answered from memory on every look, not only the first: this is the verdict that depends on the code alone.
51 expect(got.text).toContain('data-refresh="/live/home/feed"');
52 if (i === 0) marked = got.text;
53 await Bun.sleep(1);
46 let marked: string;
47 // The first look after a write schedules the one-off redraw of the five regions, which runs on this process's loop for the looks that follow; let it finish, so the sample measures the steady cost of a look.
48 write(-1);
49 marked = (await look(f.ownerCookie)).text;
50 await Bun.sleep(1_000);
51 let median = Infinity;
52 for (let sample = 0; sample < SAMPLES && !(median < APP_BUDGET_MS); sample++) {
53 const times: number[] = [];
54 for (let i = 0; i < LOOKS; i++) {
55 write(sample * LOOKS + i);
56 const got = await look(f.ownerCookie);
57 expect(got.res.status).toBe(200);
58 times.push(got.ms);
outdated

times[floor(n/4)] is the 6th fastest of 20. It lets a regression through that slows most requests. Use a bound that still fails when the typical request is over budget (median after warm-up, or one whole-sample retry), and tie it to the cause seen in the failing check log.

59 // Answered from memory on every look, not only the first: this is the verdict that depends on the code alone.
60 expect(got.text).toContain('data-refresh="/live/home/feed"');
61 await Bun.sleep(1);
62 }
63 // Every look measured a time; a missing one is a broken header, not a fast look.
64 expect(times.every((t) => Number.isFinite(t))).toBe(true);
65 times.sort((a, b) => a - b);
66 median = times[Math.floor(times.length / 2)]!;
5467 }
55 times.sort((a, b) => a - b);
56 // The median, not the slowest of twenty: one stalled look on a loaded check machine is the machine, not the code.
57 expect(times[Math.floor(times.length / 2)]!).toBeLessThan(APP_MEDIAN_MS);
68 expect(median).toBeLessThan(APP_BUDGET_MS);
5869 for (const name of ["kpis", "waiting", "panels", "asked", "feed"]) {
5970 expect(marked).toContain(`id="home-${name}"`);
6071 }

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs