import { getHeapStatistics } from "node:v8";
import { describe, expect, it, vi } from "vitest";
import { render } from "#lib/ssr/pool.ts";
import { RENDER_QUEUE_WAIT_MS, type RenderTask } from "#lib/ssr/render.ts";
vi.mock(import("node:v8"), async (original) => ({
...(await original()),
getHeapStatistics: vi.fn((await original()).getHeapStatistics)
}));
const ctx = { repo: "ada.test/infra", ref: "main" };
const markup = (source: string) => (): RenderTask => ({ kind: "markup", source, ctx });
describe("render pool", () => {
const slow = (tag: string) =>
markup(
Array.from(
{ length: 400 },
(_, i) => `## ${tag}${i}\n\n\`\`\`ts\nconst x${i} = ${i};\n\`\`\``
).join("\n\n")
)();
let warmups = 0;
const idleWorker = () => render(markup(`warm-up ${warmups++}`)(), 10_000);
it("drops a render past its timeout and keeps rendering after", async () => {
await idleWorker();
expect(await render(slow("timeout"), 1)).toBeNull();
expect(await render(markup("**ok**")(), 10_000)).toContain("ok");
});
it("drops a render that's no longer wanted once a worker is free", async () => {
expect(await render(markup("**unwanted**")(), 10_000, {}, () => false)).toBeNull();
});
it("serves a document rendered before without rendering it again", async () => {
const task = slow("cached");
const html = await render(task, 10_000);
expect(html).toContain("cached399");
expect(await render(task, 1)).toBe(html);
});
it("stops caching while the heap is near its limit", async () => {
vi.useFakeTimers({ toFake: ["Date"], now: Date.now() + 60_000 });
const real = getHeapStatistics();
vi.mocked(getHeapStatistics).mockReturnValue({
...real,
used_heap_size: real.heap_size_limit
});
const task = slow("pressure");
expect(await render(task, 10_000)).toContain("pressure399");
vi.mocked(getHeapStatistics).mockRestore();
vi.setSystemTime(Date.now() + 60_000);
await idleWorker();
vi.useRealTimers();
expect(await render(task, 1)).toBeNull();
});
it("remembers a document whose render timed out instead of retrying it each time", async () => {
const task = slow("hangs");
await idleWorker();
expect(await render(task, 50)).toBeNull();
expect(await render(task, 10_000)).toBeNull();
});
// node < 26 aborts the whole process when a worker ooms inside a builtin call
it.skipIf(Number(process.versions.node.split(".")[0]) < 26)(
"survives a render that takes its worker down, and keeps rendering after",
async () => {
const huge = markup("a\n\n".repeat(4_000_000))();
expect(await render(huge, 60_000)).toBeNull();
expect(await render(markup("**after the crash**")(), 10_000)).toContain(
"after the crash"
);
}
);
it("doesn't hold a timeout spent waiting for a worker against the document", async () => {
await idleWorker();
const busy = Array.from({ length: 16 }, (_, i) => render(slow(`queue${i}-`), 60_000));
const task = markup("**waited too long**")();
expect(await render(task, 30, {})).toBeNull();
expect(await render(task, 60_000)).toContain("waited too long");
await Promise.all(busy);
});
it("gives up on a render no worker takes in time, however long its timeout", async () => {
await idleWorker();
const busy = Array.from({ length: 200 }, (_, i) => render(slow(`lane${i}-`), 60_000, {}));
const asked = Date.now();
expect(await render(markup("**late**")(), 60_000, {})).toBeNull();
expect(Date.now() - asked).toBeLessThan(RENDER_QUEUE_WAIT_MS * 2);
await Promise.all(busy);
});
it("renders a document asked for twice at once only once", async () => {
await idleWorker();
const task = slow("twice");
const first = render(task, 10_000);
const second = render(task, 1);
const [a, b] = await Promise.all([first, second]);
expect(a).toContain("twice399");
expect(b).toBe(a);
});
it("takes turns between owners instead of serving the queue in order", async () => {
const busy = {};
let busyDone = 0;
const queued = Array.from({ length: 40 }, (_, i) =>
render(slow(`busy${i}-`), 60_000, busy).then(() => busyDone++)
);
await render(markup("**other page**")(), 60_000, {});
expect(busyDone).toBeLessThan(20);
await Promise.all(queued);
});
});