Fix freeze caused by progress bar firing onDone during asset transitions#634
Fix freeze caused by progress bar firing onDone during asset transitions#634
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThese changes improve transition handling and component lifecycle management. The home-page component replaces a boolean guard with a serialized Promise queue to properly order concurrent transition requests. The asset component adds proper cleanup on destroy, clears video sources, and guards event handlers to prevent post-destruction invocations. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
immichFrame.Web/src/lib/components/home-page/home-page.svelte (1)
152-170: Serialized transition queue looks good; a couple of minor observations.Replacing the boolean guard with a promise chain correctly serializes
handleDoneinvocations and prevents the reentrancy that caused the freeze. The.catchon the inner promise also ensures a single failed transition doesn't poison the chain for subsequent calls.Two small, optional considerations:
progressBar.restart(false)(line 158) andprogressBar.play()(line 164) are not awaited. Not awaitingplay()is intentional and correct (it resolves only when the tween reaches 1, i.e. after the full interval). But not awaitingrestart(false)meansprogress.set(0)races with the downstreamprogressBar.play()→progress.set(1)on the (newly re-assigned) tween from the duration change. In practicesetDurationreturns 0 ms whento === 0, soset(0)settles synchronously on the next microtask, but awaiting it would make the ordering explicit and robust to future changes insetDuration.The chain
transitionLock = transitionLock.then(...).catch(...)is unbounded in principle; each resolved predecessor becomes eligible for GC, so this is fine in practice, just worth being aware of if transitions are ever triggered at very high frequency.Optional hardening
transitionLock = transitionLock .then(async () => { userPaused = false; - progressBar.restart(false); + await progressBar.restart(false); $instantTransition = instant; if (previous) await getPreviousAssets(); else await getNextAssets(); await tick(); await assetComponent?.play?.(); progressBar.play(); })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@immichFrame.Web/src/lib/components/home-page/home-page.svelte` around lines 152 - 170, The transition handler handleDone should await progressBar.restart(false) before calling progressBar.play() to ensure restart's progress.set(0) completes before play's progress.set(1) runs; update the async callback inside transitionLock.then(...) in handleDone to await progressBar.restart(false) (maintaining the existing .catch(...) on the chain) so ordering is explicit and robust to future changes in setDuration.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@immichFrame.Web/src/lib/components/home-page/home-page.svelte`:
- Around line 152-170: The transition handler handleDone should await
progressBar.restart(false) before calling progressBar.play() to ensure restart's
progress.set(0) completes before play's progress.set(1) runs; update the async
callback inside transitionLock.then(...) in handleDone to await
progressBar.restart(false) (maintaining the existing .catch(...) on the chain)
so ordering is explicit and robust to future changes in setDuration.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 83dbd6b6-18bd-4894-9c07-091b51432fb4
📒 Files selected for processing (2)
immichFrame.Web/src/lib/components/elements/progress-bar.svelteimmichFrame.Web/src/lib/components/home-page/home-page.svelte
|
Closes #601 |
The progress bar's onChange handler was unconditionally calling play()
whenever the duration changed, causing onDone to fire multiple times
in rapid succession during asset transitions. This created a race
condition that caused a freeze.
Fixed by only calling play() in onChange when the progress bar is
already in a playing state. Also replaced the boolean
isHandlingAssetTransition guard with a promise-based transitionLock
to safely serialize any concurrent handleDone calls.
Summary by CodeRabbit