Repository navigation
fix(core): a multi-worker render replays overlapping tweens behind the timeline stand-in - #7231
Conversation
…e timeline stand-in The overlap and landing-mark walks compared tween parents with the stand-in the producer's GSAP stub hands out, never met it, and lost the overlaps and step times. Both now compare with the real timeline behind the stand-in.
There was a problem hiding this comment.
Verdict: REQUEST CHANGES · 1 blocker · 0 important · 0 nits · head ba5ce982
The fix is right. Both parent walks that compare against the seeked timeline (writeOf, startOnOwner) now resolve the stand-in, and the producer stub's __hfReal matches the test stand-in. The two tests on Fails without the fix: lines prove it.
- blocker: the
Commentscheck fails at this head. MovinggsapTimelineOfcarried its comment intogsap.ts, which raises that file's comment share (3/583 vs 2/576). The ratchet checks each file, so the line removed frominit.tsdoesn't offset it. Drop the doc comment ongsapTimelineOf(the name and the__hfRealread carry it), or fold it into the name.
Scope
I read all 5 files, every parent-identity walk in adapters/gsap.ts and init.ts, and the stub's stand-in in producer/stubs/hf-early-stub.ts. structure.owner reaches startOnOwner unchanged, so the resolution there covers every landing-mark caller. CI, regression and the player jobs were still running when I reviewed. Only Comments had failed.
— Genesis lane B
Edit accuracy: accurate 267 (base branch 267), smooth 91 of thoseThe gate passes. Quarantined, measured but not gated (8)
Unstable (1)
|
There was a problem hiding this comment.
Verdict: APPROVE — 1 resolved, 0 open, 0 new · ba5ce982 → d3cb83a9
✅ The only change since ba5ce982 is the removed doc comment, and Comments passes. CI is red, but not from this change. Test (studio) and SDK: unit + contract + smoke failed on 504s while downloading setup files (ffmpeg-static, setup-test-workspace). Studio: timeline viewport gate missed its p95 timing budget. Test (runtime), Producer unit and integration, Typecheck and Lint pass. Re-run the failed jobs before merge.
— Genesis lane B
* chore: release v0.9.16 * chore: format v0.9.16 release notes * chore: add heygen-com#7228 and heygen-com#7231 to v0.9.16 notes * chore: add heygen-com#7217 heygen-com#7224 heygen-com#7225 heygen-com#7226 heygen-com#7229 heygen-com#7233 to v0.9.16 notes
…eview Adopts or partially adopts 11 groups: multi-worker tween replay behind the timeline stand-in (heygen-com#7231), template entries in the shared compile stage (heygen-com#7217), HYPERFRAMES_CACHE_DIR and HYPERFRAMES_CONFIG_DIR for every per-user cache and settings file (heygen-com#7224, heygen-com#7229; HeyGen credentials stay under HEYGEN_CONFIG_DIR), WebKit audio clock (heygen-com#7225), packet-based video length (heygen-com#7233), HLG tone mapping (heygen-com#7234), fetch network cause (heygen-com#7236), .hyperframesignore in lint (heygen-com#7239), info --media (heygen-com#7235), lint priority (heygen-com#7244), check --budget (heygen-com#7245) and the unknown-command answer (heygen-com#7247). bun.lock gains only the lint `ignore` edge from heygen-com#7239, already resolved. Watermark advances to 0a6746e. Co-authored-by: Jerrai <jerrai@heygen.com> Co-authored-by: Miguel Ángel <miguel.sierra@heygen.com> Co-authored-by: WaterrrForever <miao.yang@heygen.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
What
A multi-worker or chunked render now replays overlapping tweens when the composition's timeline came through the producer's GSAP stub, so
-w 8matches-w 1frame for frame on the repro in #7223.Why
The replay from #6707 decides which frames to re-render by finding tweens that write the same property at the same time. It finds them by walking each tween's parents up to the timeline being seeked. In a render, that timeline is the stand-in the producer's early GSAP stub hands the composition (
__hfRealholds the real one), so the walk never meets it. It walks past the real timeline instead, which is paused, gives up, and finds no overlaps. No frame was replayed, and the output matched 0.8.214. The unit tests seek a real timeline, which is why they passed. Preview never goes through the stub, so playback was unaffected.Related work
Fixes #7223. Follows #6707.
How
gsapTimelineOf(stand-in to real timeline) moves frominit.tsinto the GSAP adapter, its one owner, andinit.tsimports it.gsapTimelineOf(timeline). Seeks still go through the stand-in, which flushes queued tweens first.startOnOwner) had the same comparison: behind a stand-in, every step lost its time, so two steps at one time were not re-applied in authored order after the playhead came back onto them. It now compares withgsapTimelineOf(owner)too.timeline.tswalks tween parents up to the registered root to build the clip list; I found no render output that depends on it, so it is left for a separate change if one turns up.gsapStandIn.test-helpers.ts, shared by both test files.Test plan
gsap.order.test.tsadds "gives every frame the same value when the producer hands out a stand-in for the timeline", 8 interleaved workers seeking a stand-in shaped like the stub's. Fails without the fix:expected [ 56, 1.040171 ] to deeply equal [ 56, 1.449293 ].gsap.steps.test.ts: "shows two steps on one later time in authored order after the playhead comes back onto %s" now runs for a timeline and for the producer's stand-in. Fails without the fix:expected 'hidden' to be 'visible'.tsc --noEmit, oxlint and oxfmt are clean.-w 1vs-w 8: 59 of 90 frames differ (17 to 75).-w 1vs-w 8: 0 of 90 differ (t = 0.8 s: 1.420 in both).-w 1vs 0.9.15-w 1: 0 differ.