Repository navigation
fix(cli): Studio renders take the same one-render-slot lock as the CLI - #7459
Conversation
There was a problem hiding this comment.
Requesting changes at c1d2da9c for one reason: the PR body is missing the required line.
Blocker: this is a fix PR (fix(cli), Fixes #7457), so its body needs a fails without the fix: line that names a test. The Test plan says "With the old studioServer.ts restored, the first two fail", but it doesn't say which tests or put them on that line. For example:
fails without the fix:
packages/cli/src/server/studioServer.renderLock.test.ts"makes a second render wait, and say so, until the first ends" and "lets Cancel end a wait without freeing the slot the first render holds" fail on main'sstudioServer.ts(both renders run at once and no stage says "Waiting for another render"); with the fix, 4 of 4 pass.
The code looks correct (no blocker):
acquireRenderLockis called after the producer loads and the browser resolves, and beforeexecuteRenderJob. The release is infinally, so the slot is freed on complete, fail and cancel.- Cancel while waiting:
pauserejects with the signal's reason. The existingcatchseessignal.abortedand marks the job cancelled instead of failed.RenderLockUnwritableand stale-break errors reachstate.errorwith the lock's own message. - Calling
acquireRenderLockdirectly keeps a single copy of theHYPERFRAMES_RENDER_LOCK=offand cache-dir policy. Two Studio renders in the same process still queue, because the holder's pid is alive and isn't treated as stale.
Optional (not blocking): after the slot is acquired, state.stage keeps showing "Waiting for another render (…)" until the producer reports its first currentStage. Clearing it, or setting a "Starting render" stage, right after acquireRenderLock returns would stop the UI from looking stuck behind a render that has already finished.
CI at this head: regression, Player perf, PR captures and Comments passed. CI, CodeQL and preview-regression were still running, and Windows render verification was queued.
There was a problem hiding this comment.
Approving at 622a1eb1. Both review points are resolved.
- Blocker resolved: the
fails without the fix:line now names the file and the two tests ("makes a second render wait, and say so, until the first ends" and "lets Cancel end a wait without freeing the slot the first render holds"). - Optional point addressed:
state.stage = undefinedright afteracquireRenderLockreturns clears the wait text as soon as the slot is taken. The new assertion in the first test checks this with a mocked producer that never reports a stage, so the assertion would fail without that line.packages/cli/tsconfig.jsondoesn't setexactOptionalPropertyTypes, so assigningundefinedtype-checks. - The interdiff from
c1d2da9cis just these two lines plus the assertion. The rest of the change is what I reviewed before and has no blocker.
CI at this head: regression, Player perf and PR captures passed. CI, CodeQL, Comments, preview-regression and Windows render verification were still running. Merge only after they're green.
…heygen-com#7456 and the heygen-com#7439 docs heygen-com#7459: Studio renders take the same one-render-slot lock as the CLI and say they are waiting; Cancel ends the wait. heygen-com#7463: deleting an animated group parses its script once instead of once per tween. heygen-com#7454: seam-gate awaits the async player seek (both skill mirrors). heygen-com#7456: the engine browser test project gets 30 s per test. heygen-com#7439: current ChatGPT and Claude setup steps in the MCP guide. Co-Authored-By: Claude Sonnet <noreply@anthropic.com>
…ve more; advance watermark Twelve commits, PRs 7453-7468, issues 7457-7465 and eleven pin moves are recorded with their evidence in the continued ledger, DECISIONS and UPSTREAM. Adopted: heygen-com#7338, heygen-com#7459, heygen-com#7463, heygen-com#7454, heygen-com#7456 and the heygen-com#7439 docs; heygen-com#6732 was already ported. Deferred: heygen-com#7455, heygen-com#7437. Not applicable: heygen-com#7453, heygen-com#7269, heygen-com#7464. The watermark moves to 9e346f9, PR heygen-com#7468, issue heygen-com#7465; four new PRs are pinned and the eleven moved pins re-pinned at their current heads. FORK.md records the fork-only differences in the heygen-com#7338 port; the roadmap tracks the standalone scripts that keep a bare mkdtemp and issue heygen-com#7458. Co-Authored-By: Claude Sonnet <noreply@anthropic.com>
What
Studio's render route now takes the CLI's per-account render slot before it runs a render, and releases it when the render completes, fails or is cancelled.
Why
The CLI runs one local render at a time per user account, but Studio's route called the producer directly, so Studio renders ran side by side with each other and with CLI renders, each sizing its workers to the whole machine.
Related work
Fixes #7457.
How
acquireRenderLockinutils/renderLock.tsalready owns the slot policy (theHYPERFRAMES_RENDER_LOCK=offswitch, theHYPERFRAMES_CACHE_DIRlocation, stale-holder takeover, unwritable-folder errors). The CLI'sacquireRenderSlotonly adds console text around it, so Studio callsacquireRenderLockdirectly and no second copy of the policy exists. While it waits the job'sstagereads "Waiting for another render ()"; Cancel passes the job's abort signal, so it ends the wait and the job reads as cancelled. A stale-break or unwritable error fails the job with the lock's own message.Test plan
fails without the fix:
packages/cli/src/server/studioServer.renderLock.test.ts"makes a second render wait, and say so, until the first ends" and "lets Cancel end a wait without freeing the slot the first render holds" fail on main'sstudioServer.ts(both renders run at once and no stage says "Waiting for another render"); with the fix 4 of 4 pass. The "until the first ends" test also fails if the wait words are left on the job after the slot is taken.studioServer.renderLock.test.ts(second render waits and says so until the first ends; Cancel while waiting leaves the first render's slot held; a failed render frees the slot;HYPERFRAMES_RENDER_LOCK=offruns both side by side). 4 pass, 3 runs in a row. With the oldstudioServer.tsrestored, the first two fail.studioServer.test.ts(44) andstudioServer.renderBrowser.test.ts(5) still pass; oxlint and oxfmt are clean on the changed files.tsc --noEmitreports 5 errors, all missing@hyperframes/inspector/live(a package not built in my checkout); none in the changed files.