Skip to content

test(motion): a retarget behind a block fails by name when starved - #10784

Merged
cixzhang merged 1 commit into
meta:mainfrom
vjeux:test/retarget-starvation-named
Nov 9, 2026
Merged

cixzhang merged 1 commit into
meta:mainfrom
vjeux:test/retarget-starvation-named

Conversation

@vjeux

@vjeux vjeux commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Maintainer impact

Under load, the retarget-behind-a-block case fails with only the raw JSON of its reads. On main 738919b, 11 of 90 runs at 4 workers on two cores failed that way. In 10, the compositor presented no frame for 67 ms or more after the block, leaving too few frames to judge. The eleventh missed the fit by 0.02 px over its bound.

Intended invariant

The case keeps its claim and every check with its bound:

  • at least 3 frames in the block, and 3 in the 130 ms after it;
  • every frame within 4 px of a call starting at a frame after the block, from the value and velocity on screen there;
  • the call's own clock misses the same frames by over 20 px.

Change

61afefe changes one spec file:

  • The two frame counts become requireFrames over the block and the 130 ms after it. They count the frames the controls' clock dates. Gaps are read past the window's edges, so a hole at the window's end counts. A starved run fails as FrameStarvationError, with its frame count and longest gap.
  • The two fit checks keep their bounds. Their messages say in words what they measured.
  • No bound or window changes, so nothing is loosened.

Evidence

  • At 61afefe, 1 worker on two pinned cores: the case passes 20 of 20 in Chromium.
  • Not-for-landing, 1 worker, the cast's frames 30 to 150 ms after the block removed:
    • main 1d1d9ad (727c4e6) fails 3 of 3 with the raw JSON.
    • 61afefe (dec3b2a) fails 3 of 3 as FrameStarvationError: "the page drew 1 frame … where the proof needs 3. No frame came for 133.3 ms".
  • Report-only, 4 workers on two cores with 2 busy loops:
  • Two of 260 such runs missed the fit by just over 4 px, each with 3 or 4 frames after the block. The bound stays. A follow-up judges the hand-off frame those misses came from.
  • Product/runtime behavior verified unchanged: test-only.
  • CI impact: none.

Scope

  • No intended public API, product behavior, visual direction, or policy change.
  • Product changes discovered during the work were removed or split.
  • Public text and artifacts contain no internal Meta context.

Testing

  • Static, at 61afefe: typecheck, CI=true ESLint and Prettier on the spec, and review:pre pass.
  • At 61afefe, 1 worker: the spec passes 66 of 66 (×3) in Chromium on two pinned cores. CI's WebKit command (--cpus=4, CI=1, LP_NUM_THREADS=4) passes it 150 of 150 (×10), with 70 skipped by engine gates.
  • Pinned runs used two cores no other process or container could use. Their busy share stayed at background level before and after each round.

@vercel

vercel Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
astryx Ready Ready Preview Nov 9, 2026 2:53pm UTC

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Nov 9, 2026
@astracat-bot

astracat-bot Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

AI review status for this pull request.

Review status Updated
🟢 Reviewed (for maintainers only) Nov 9, 2026, 2:57 PM UTC

@github-actions

github-actions Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

PR Analysis Report

🔎 Preview · 61afefe

Storybook · Sandbox · built from this PR's head

Package size: no published package changed; no new dependencies.

API changes: none in this pull request

Committed API report behind this build: cli 29 rows, core 36 rows, theme-butter 1 row, theme-y2k 1 row; run pnpm api:report.

Not run on this PR: add ci:run-visual, ci:run-a11y or ci:run-rtl to run them.


Generated by PR Enrichment workflow | View full report

@astracat-bot astracat-bot Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved pending CI: CI has not run on this head yet. The retarget-behind-a-block case keeps its windows and bounds, and a starved run now fails as FrameStarvationError; both variants pass on this head in Chromium.

Next: mark the pull request ready for review, and a maintainer adds the ci:run label so CI runs on this fork branch.

  • Optional: the fit message rounds with toFixed(1), so a 4.02 px miss prints as "4.0 px (at most 4 px)"; two decimals keep it readable as a failure (inline note).
  • Optional: sort onClock with inPresentationOrder so a late-stamped frame cannot inflate the reported gap (inline note).

[Automated review]

// 100 ms after the block. Too few frames there cannot tell the call's
// clock from the screen's, so such a run fails by name, with its gaps.
// The gaps are read on the controls' clock, past the window's edges too.
const onClock = dated.map(({x, at}) => ({t: at, x}));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: onClock keeps the cast's stamp order, but its t is the controls' clock. Under load, a frame stamped late sits after frames it came before, and requireFrames reads gaps between array neighbours, so the reported longest gap can grow: frames at 5, 30, 47 and 160 ms after the block report 113 ms in time order and 130 ms when the frame at 30 is stamped late. The frame count and the pass or fail do not change.

const onClock = inPresentationOrder(dated.map(({x, at}) => ({t: at, x})));

inPresentationOrder is already exported by the harness.

The retarget-behind-a-block case counted its frames with bare expects
whose message was the raw JSON of its reads. On a loaded runner the
compositor can present no frame for over 100 ms after the block, and
the case then failed with only that JSON. It now asks requireFrames
for the frames in the block and after it, read on the controls' clock,
so a starved run fails as FrameStarvationError with its gaps. The fit
checks say in words what they measured.

@astracat-bot astracat-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved pending CI: CI has not run on this head yet. The retarget-behind-a-block case keeps its windows and bounds, a starved run now fails as FrameStarvationError, and both variants pass on this head in Chromium.

Next: mark the pull request ready for review, and a maintainer adds the ci:run label so CI runs on this fork branch.

  • Optional: the fit message rounds with toFixed(1), so a 4.02 px miss prints as "4.0 px (at most 4 px)"; two decimals keep it readable as a failure (inline note).
  • Optional: sort onClock with inPresentationOrder so a late-stamped frame cannot inflate the reported gap (see the open inline thread on that line).

[Automated review]

expect(read.worst, JSON.stringify(read)).toBeLessThanOrEqual(4);
expect(
read.worst,
`the frames miss the call, started at a frame after the block from the value and the velocity on screen there, by ${read.worst.toFixed(1)} px (at most 4 px): ${JSON.stringify(read)}`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: toFixed(1) prints the 4.02 px miss from the description as "by 4.0 px (at most 4 px)", which reads as a pass while the check fails; only the JSON after it shows 4.02. Two decimals keep the words honest:

`the frames miss the call, started at a frame after the block from the value and the velocity on screen there, by ${read.worst.toFixed(2)} px (at most 4 px): ${JSON.stringify(read)}`,

@cixzhang cixzhang added the ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) label Nov 9, 2026
@cixzhang

cixzhang commented Nov 9, 2026

Copy link
Copy Markdown
Contributor

/approve-spec 61afefe

@vjeux
vjeux marked this pull request as ready for review November 9, 2026 15:38
@cixzhang
cixzhang merged commit 6ad0656 into meta:main Nov 9, 2026
253 of 265 checks passed
@vjeux
vjeux deleted the test/retarget-starvation-named branch November 9, 2026 19:31

This branch was successfully deployed

1 active deployment
Preview — 61afefe3 Deployed Nov 9, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:run A maintainer lets this outside contributor's pull request run CI (AST-030 FR17) CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants