Skip to content

Spec 018 T005: held pages in the render service, behind RENDER_REUSE - #957

Merged
adamjohnwright merged 4 commits into
mainfrom
spec018/t005-held-pages-2
Nov 13, 2026
Merged

adamjohnwright merged 4 commits into
mainfrom
spec018/t005-held-pages-2

Conversation

@adamjohnwright

Copy link
Copy Markdown
Contributor

Spec 018 (render page reuse), T005: held pages in the render service, behind RENDER_REUSE. Also ticks T002, whose done condition was a first run of the comparison in reuse mode.

What changes

  • tools/render/pages.ts (new): the pool.
    • With reuse on, it keeps a page that has drawn a figure, at most one per concurrent render, each in a browser context of its own.
    • A page is held only after a figure that succeeded and left the page movable. A page whose figure failed is closed, and the next figure loads a new one.
    • No page is ever given to two figures at once.
    • With reuse off, every figure has a fresh page and context, as before.
  • render-core.ts: a nav option.
    • A held page is moved with the render page's __renderNavigate (T003, Spec 018 T003: the render page's entry point for a held page #877) instead of being loaded again.
    • The wait is only for the host that move made; any other host is a previous figure's.
    • The readiness handle is disposed. Undisposed, it kept every figure the page drew in memory (research R4 result, 2).
    • render() now reports whether the page can still be moved: a PDF is printed from the SVG put in the page's place, and a site built before T003 has no entry point.
  • service.ts:
    • RENDER_REUSE=on turns held pages on. Off stays the default until the comparison (T009) passes.
    • The comment above getBrowser() is rewritten to say what reuse rests on.
    • /health gains reuse, and with it on, reused. reuse-compare reads both before it trusts a run; the rest of the health contract is T008's.
  • README: the setting, and how held pages work.

Not changed: what happens to a page after a browser problem, a timeout or a browser restart, and replacement by count, memory or build. Those are T006 and T007.

Tests

pages.spec.ts, 9 tests. Each is seen failing against one mutant:

  • reuse ignored;
  • no cap on held pages;
  • a page left on the list while it draws (two figures share it);
  • a failed page kept;
  • the "still movable" check ignored;
  • a close that throws.

render-core.spec.ts, 3 new tests. Each is seen failing against one mutant:

  • every page loaded instead of moved;
  • the readiness handle kept;
  • any host waited for, not just the one the move made;
  • a refused move ignored.

service.spec.ts: /health with reuse unset says reuse: false and has no reused.

Preflight: all 14 steps ok, including "render, live".

The first reuse run of the comparison (T002)

tools/render/reuse-compare.ts --mode reuse against beta's site, which has T003 and T004 built in. The sample was 20 SVG requests: reactions, reaction layouts, a diagram dark, with subpathways off, with a selection and with a highlight, an illustration, the overview of two species, and two analysis tokens. Each was drawn listed, reversed and in ten runs of pairs. Each difference was then drawn again through two services on this host.

What differed Kind Detail
Genome-wide view after the mouse overview Leak One label of 7,604 wraps onto 3 lines on a held page and 5 on a fresh one. Repeatable both ways. Seen only at the service's 1,600 × 1,000 viewport. The cause is in FoamTree's label fitting and isn't found yet.
Illustration with an analysis token Fresh renders vary One element's style is written before or after its class. Two fresh pages differ the same way.
Highlight on R-HSA-69620 Fresh renders vary A halo's last point is 4 px apart. Two fresh pages differ the same way.
R-MMU-69620 answers 500 Sample error The local release files hold only human diagrams, so it fails on fresh pages too.
R-HSA-9844549 with a token answers 500 Did not recur It drew normally when drawn again.

All of these are recorded in tasks.md under a new task, T012, which T009 now waits on. RENDER_REUSE stays off by default, so nothing served changes.

The service's own initial bundle is unaffected: no site code changes, only a contract type.

🤖 Generated with Claude Code

adamjohnwright and others added 4 commits November 13, 2026 15:14
With RENDER_REUSE=on the service keeps a page that has drawn a figure,
one per concurrent render, each in a browser context of its own, and
moves it to the next figure inside the app with __renderNavigate
instead of loading it again; it waits only for the host that move made,
and lets go of the readiness handle, which otherwise kept every figure
the page drew. A page is held only after a figure that succeeded and
left it movable (a PDF prints in its place). Off, the default until the
comparison (T009) has passed, every figure has a fresh page as before.

/health says reuse, and with it on reused, which reuse-compare reads
before trusting a run; the rest of the health contract is T008's.

Tests seen failing: the pool with reuse ignored, no cap, a page left on
the list while drawn, a failed page kept, reusable ignored and a close
that throws; the move with every page loaded, the handle kept, any host
waited for and a refused move ignored.

T002's first reuse run (20 SVGs, three orders) is recorded in tasks.md:
one leak (the overview after another species' overview wraps one label
differently), two kinds of fresh render that vary by themselves, and a
sample error; they are T012.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main lowered the lint totals (#956), and the ratchet compares with main's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@adamjohnwright
adamjohnwright merged commit 8c69f3b into main Nov 13, 2026
8 checks passed
@adamjohnwright
adamjohnwright deleted the spec018/t005-held-pages-2 branch November 13, 2026 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant