Skip to content

fix(genui-a2ui-prompt): serialize build:api after build to avoid rspack cache race#2794

Merged
upupming merged 2 commits into
mainfrom
fix/genui-a2ui-prompt-rslib-cache-race
Jun 4, 2026
Merged

fix(genui-a2ui-prompt): serialize build:api after build to avoid rspack cache race#2794
upupming merged 2 commits into
mainfrom
fix/genui-a2ui-prompt-rslib-cache-race

Conversation

@upupming
Copy link
Copy Markdown
Collaborator

@upupming upupming commented Jun 4, 2026

Summary

pnpm turbo api-extractor can flake on code-style-check / test-api with:

thread 'tokio-N' panicked at crates/rspack_storage/src/filesystem/db/transaction/mod.rs:53:7:
Transaction already in progress by process M:rslib-node in directory '.../packages/genui/a2ui-prompt/node_modules/.cache/rspack/<hash>/.temp'
Aborted (core dumped)
[ELIFECYCLE] Command failed with exit code 134.

The race: @lynx-js/genui#api-extractor (in packages/genui/turbo.json) depends on both //#build and @lynx-js/genui-a2ui-prompt#build:api. The build chain triggers genui-a2ui-prompt#build, and at the same time turbo schedules genui-a2ui-prompt#build:api. Both scripts are literally rslib build, both produce the same rspack content hash, and both write to the same node_modules/.cache/rspack/<hash>/.temp directory. rspack's own filesystem-storage transaction lock catches the conflict and aborts the second process with SIGABRT (exit 134).

Fix: add dependsOn: ["build"] to build:api in packages/genui/a2ui-prompt/turbo.json so turbo serializes the two. build runs first, releases the rspack transaction on exit; build:api then runs against a warm content-addressed cache.

This is independent from the api-extractor lock TOCTOU fix in #2780 — that one fixed the JSON lockfile race in run-api-extractor.mjs; this one is rspack's internal cache directory, surfaced by turbo's task graph rather than my lock script.

Scoped to just genui-a2ui-prompt because that's the only package where I have a panic trace. openui/a2ui/a2ui-catalog-extractor share the same build/build:api shape but use tsc not rslib, so they don't hit the rspack lock. If they start flaking we can extend the same dep.

Test plan

  • code-style-check (which runs pnpm turbo api-extractor) passes on this PR.
  • No regression in test-api (which runs pnpm turbo api-extractor -- --local).
  • Local: pnpm turbo api-extractor --filter=@lynx-js/genui still produces the genui api reports without panic.

Summary by CodeRabbit

  • Chores
    • Updated build task dependencies to enforce correct execution order within the build pipeline.

…ck cache race

genui#api-extractor depends on both //#build (which transitively
triggers genui-a2ui-prompt#build) and genui-a2ui-prompt#build:api.
Their scripts are identical (`rslib build`) and write to the same
node_modules/.cache/rspack/<hash>/.temp directory, so turbo runs them
concurrently and rspack's filesystem transaction lock aborts the second
one with `Transaction already in progress by process N:rslib-node`
(SIGABRT / exit 134), surfacing as a flaky `code-style-check` /
`test-api` job.

Add `dependsOn: ["build"]` to build:api so turbo runs them serially.
The second rslib invocation still happens (turbo cache keys differ
across tasks) but rspack's content-addressed cache is warm, so it's
fast and no longer races.
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jun 4, 2026

⚠️ No Changeset found

Latest commit: 545fcc9

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 4, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e68202b6-f5bb-4f1d-b774-c17422c6addd

📥 Commits

Reviewing files that changed from the base of the PR and between baf40ba and 545fcc9.

📒 Files selected for processing (1)
  • packages/genui/a2ui-prompt/turbo.json

📝 Walkthrough

Walkthrough

Configuration change to turbo.json that establishes task execution ordering by making the build:api task depend on the build task, ensuring the correct sequence of operations in the monorepo build pipeline.

Changes

Build Task Dependencies

Layer / File(s) Summary
Build:API task dependency
packages/genui/a2ui-prompt/turbo.json
The build:api task's dependsOn configuration now includes the build task, enforcing correct execution order in the task pipeline.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Suggested reviewers

  • HuJean
  • PupilTong
  • Sherry-hue
  • gaoachao
  • fzx2666-fz

Poem

🐰 A build task hops in line,
before its API cousin shines,
Dependencies, now arranged just right,
Turbo flows with ordered might!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: serializing build:api after build to avoid rspack cache race conditions in genui-a2ui-prompt.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/genui-a2ui-prompt-rslib-cache-race

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 4, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Jun 4, 2026

Merging this PR will improve performance by 7.39%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
✅ 86 untouched benchmarks
⏩ 26 skipped benchmarks1

Performance Changes

Benchmark BASE HEAD Efficiency
transform 1000 view elements 43.3 ms 40.3 ms +7.39%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing fix/genui-a2ui-prompt-rslib-cache-race (545fcc9) with main (baf40ba)

Open in CodSpeed

Footnotes

  1. 26 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@upupming
Copy link
Copy Markdown
Collaborator Author

upupming commented Jun 4, 2026

Self-note from running this on PR #2793:

test-api flips to a different failure on this branch: @lynx-js/genui-a2ui:build:api runs tsc and errors with Cannot find module '@lynx-js/genui-a2ui-prompt' or its corresponding type declarations.

Cause: the a2ui-prompt:build:api → build dep I added pushes a2ui-prompt's dist generation later in the schedule, but a2ui:build:api still has dependsOn: [], so it starts immediately and runs tsc before a2ui-prompt's .d.ts is on disk.

So this fix is only half right — it kills the same-package rspack race in a2ui-prompt, but breaks the cross-package consumption order (a2ui imports from a2ui-prompt). The proper fix needs to cascade across packages too — either:

  • add ^build:api to every genui-sub build:api so they wait on upstream sub builds, or
  • drop build:api entirely and rewire genui#api-extractor.dependsOn to use the standard build task.

Pausing this PR; will rework before un-drafting.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 4, 2026

UI Judge

GEQI weighted score: 62.8 / 100 across 8 examples.
Average visual-correctness score: 3.3 / 5.

Dimension Weight Average Results Status
Usability & Interaction 30% 3.1 / 5 8 OK
Visual & Aesthetics 25% 3.3 / 5 8 OK
Consistency & Standards 15% 3.4 / 5 8 OK
Architecture & UX Writing 15% 3 / 5 8 OK
Accessibility & Performance 15% 2.9 / 5 8 OK
# Example Visual Correctness Usability & Interaction (30%) Visual & Aesthetics (25%) Consistency & Standards (15%) Architecture & UX Writing (15%) Accessibility & Performance (15%) GEQI Page Status
1 recs 2 / 5 2 / 5 3 / 5 2 / 5 2 / 5 2 / 5 45 / 100 preview OK
2 cast-grid 5 / 5 3 / 5 4 / 5 5 / 5 5 / 5 3 / 5 77 / 100 preview OK
3 citywalk-list 2 / 5 3 / 5 3 / 5 2 / 5 1 / 5 3 / 5 51 / 100 preview OK
4 fridge-search 3 / 5 3 / 5 3 / 5 4 / 5 3 / 5 3 / 5 63 / 100 preview OK
5 trip-planner 2 / 5 3 / 5 3 / 5 2 / 5 2 / 5 2 / 5 51 / 100 preview OK
6 weather-current 5 / 5 5 / 5 4 / 5 5 / 5 5 / 5 4 / 5 92 / 100 preview OK
7 product-card 5 / 5 4 / 5 4 / 5 5 / 5 4 / 5 4 / 5 83 / 100 preview OK
8 workout-plan 2 / 5 2 / 5 2 / 5 2 / 5 2 / 5 2 / 5 40 / 100 preview OK
Details

Result 1

  • Example: recs
  • Dimension: visual-correctness
  • Visual correctness: 2 / 5
  • GEQI dimensions:
    • Usability & Interaction: 2 / 5 (30%)
    • Visual & Aesthetics: 3 / 5 (25%)
    • Consistency & Standards: 2 / 5 (15%)
    • Architecture & UX Writing: 2 / 5 (15%)
    • Accessibility & Performance: 2 / 5 (15%)
  • Task: The A2UI playground preview should show date-night dining recommendations for Moonlight Terrace, Pinewood Bistro, and Sea Breeze Kitchen.

Result 2

  • Example: cast-grid
  • Dimension: visual-correctness
  • Visual correctness: 5 / 5
  • GEQI dimensions:
    • Usability & Interaction: 3 / 5 (30%)
    • Visual & Aesthetics: 4 / 5 (25%)
    • Consistency & Standards: 5 / 5 (15%)
    • Architecture & UX Writing: 5 / 5 (15%)
    • Accessibility & Performance: 3 / 5 (15%)
  • Task: The A2UI playground preview should show a cast grid for the short film Night Notes, including Lin Xia and Zhou Ning cast cards.

Result 3

  • Example: citywalk-list
  • Dimension: visual-correctness
  • Visual correctness: 2 / 5
  • GEQI dimensions:
    • Usability & Interaction: 3 / 5 (30%)
    • Visual & Aesthetics: 3 / 5 (25%)
    • Consistency & Standards: 2 / 5 (15%)
    • Architecture & UX Writing: 1 / 5 (15%)
    • Accessibility & Performance: 3 / 5 (15%)
  • Task: The A2UI playground preview should show weekend citywalk coffee picks with Rooftop Brew Room, Corner Canvas Lab, and Late Sun Roastery.

Result 4

  • Example: fridge-search
  • Dimension: visual-correctness
  • Visual correctness: 3 / 5
  • GEQI dimensions:
    • Usability & Interaction: 3 / 5 (30%)
    • Visual & Aesthetics: 3 / 5 (25%)
    • Consistency & Standards: 4 / 5 (15%)
    • Architecture & UX Writing: 3 / 5 (15%)
    • Accessibility & Performance: 3 / 5 (15%)
  • Task: The A2UI playground preview should show refrigerator search results with Siemens, Hualing, Haier, and Midea product cards.

Result 5

  • Example: trip-planner
  • Dimension: visual-correctness
  • Visual correctness: 2 / 5
  • GEQI dimensions:
    • Usability & Interaction: 3 / 5 (30%)
    • Visual & Aesthetics: 3 / 5 (25%)
    • Consistency & Standards: 2 / 5 (15%)
    • Architecture & UX Writing: 2 / 5 (15%)
    • Accessibility & Performance: 2 / 5 (15%)
  • Task: The A2UI playground preview should show a Kyoto 48-hour trip planner with Day 1 and Day 2 itinerary sections, including Monkey Park Viewpoint.

Result 6

  • Example: weather-current
  • Dimension: visual-correctness
  • Visual correctness: 5 / 5
  • GEQI dimensions:
    • Usability & Interaction: 5 / 5 (30%)
    • Visual & Aesthetics: 4 / 5 (25%)
    • Consistency & Standards: 5 / 5 (15%)
    • Architecture & UX Writing: 5 / 5 (15%)
    • Accessibility & Performance: 4 / 5 (15%)
  • Task: The A2UI playground preview should show the current weather for Austin, TX, including clear skies with light breeze.

Result 7

  • Example: product-card
  • Dimension: visual-correctness
  • Visual correctness: 5 / 5
  • GEQI dimensions:
    • Usability & Interaction: 4 / 5 (30%)
    • Visual & Aesthetics: 4 / 5 (25%)
    • Consistency & Standards: 5 / 5 (15%)
    • Architecture & UX Writing: 4 / 5 (15%)
    • Accessibility & Performance: 4 / 5 (15%)
  • Task: The A2UI playground preview should show a Wireless Headphones Pro product card with a visible Add to Cart action.

Result 8

  • Example: workout-plan
  • Dimension: visual-correctness
  • Visual correctness: 2 / 5
  • GEQI dimensions:
    • Usability & Interaction: 2 / 5 (30%)
    • Visual & Aesthetics: 2 / 5 (25%)
    • Consistency & Standards: 2 / 5 (15%)
    • Architecture & UX Writing: 2 / 5 (15%)
    • Accessibility & Performance: 2 / 5 (15%)
  • Task: The A2UI playground preview should show a weekly workout plan with five days from Monday Ramp-Up through Friday Conditioning.

Workflow run

@upupming upupming marked this pull request as ready for review June 4, 2026 07:49
@upupming upupming enabled auto-merge (squash) June 4, 2026 07:49
@upupming upupming merged commit 7ad601a into main Jun 4, 2026
44 checks passed
@upupming upupming deleted the fix/genui-a2ui-prompt-rslib-cache-race branch June 4, 2026 07:54
upupming added a commit that referenced this pull request Jun 4, 2026
… race

genui-a2ui-prompt's build:api was identical to build (both 'rslib build')
and ran right after it, rewriting the same dist/. With no turbo edge
between build:api and genui-cli#build (both only depend on #build), they
ran concurrently: rslib cleans dist and emits index.js before index.d.ts,
so genui-cli's tsc could read dist/ in the window where the .d.ts was
missing -> TS2307/TS7016 'Cannot find module @lynx-js/genui-a2ui-prompt'.

Point the genui api-extractor task at #build instead and remove the
duplicate build:api. dist is now written once, before its consumers, so
the race is gone. This also subsumes #2794: with no second 'rslib build'
there is no concurrent rspack cache transaction to conflict.

Verified locally: 'turbo api-extractor --filter=@lynx-js/genui*
--force -- --local' reproduced the TS error before, and passes 3/3 after.
upupming added a commit that referenced this pull request Jun 4, 2026
The lock existed only to serialize the in-script 'pnpm run build' calls
(concurrent rslib builds corrupting rspack's cache, #2794). That in-script
build is gone — turbo now builds each package before its api-extractor
task — so the api-extractor script only runs the extractor binary, which
writes per-package outputs with no shared mutable state. Concurrent runs
need no mutual exclusion, so the link/reap lock (and its stale-reaping
TOCTOU flagged in review) is removed entirely.

Verified: forced 'turbo api-extractor -- --local' across the genui graph
-> 26/26 tasks, all 'API Extractor completed successfully', 0 TS errors.
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.

2 participants