Something went wrong. Try again.
Monorepo for Tangled forked from tangled.org/core
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117import { 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("<strong>ok</strong>"); });
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( "<strong>after the crash</strong>" ); } );
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("<strong>waited too long</strong>"); 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); });});