fix: prevent intermittent clip splitting failures#403
fix: prevent intermittent clip splitting failures#403mvanhorn wants to merge 1 commit intojamiepine:mainfrom
Conversation
Two changes to address the race condition causing "Failed to split clip": Backend (stories.py): Added with_for_update() to the item query in split_story_item so concurrent requests for the same clip are serialized via a row lock instead of racing. Frontend (StoryTrackEditor.tsx): Guard handleSplit with splitItem.isPending to prevent rapid double-clicks from firing multiple mutations before the first completes. Fixes jamiepine#366
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe changes address a race condition in the clip splitting feature by adding concurrency safeguards. The frontend prevents initiating multiple concurrent splits via a pending state check, while the backend enforces row-level database locking to ensure consistent reads during split operations. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
Summary
Addresses the intermittent "Failed to split clip" error reported in #366 with two changes targeting the race condition.
Root cause
split_story_iteminbackend/services/stories.pyqueries the item, mutates it, creates a new item, and commits - all without any row locking. Rapid double-clicks (or query invalidation re-renders triggering concurrent mutations) can cause the second request to read stale state from the first, leading to a 404 or inconsistent trim values.Changes
Backend (
backend/services/stories.py): Addedwith_for_update()to the item query insplit_story_item(line 490). This acquires a row-level lock so concurrent split requests on the same clip are serialized rather than racing.Frontend (
app/src/components/StoriesTab/StoryTrackEditor.tsx): AddedsplitItem.isPendingguard tohandleSplit(line 503). Prevents the callback from firing while a split mutation is already in flight, which is the most common trigger for the race.Testing
The race is intermittent by nature, so there's no deterministic repro. The row lock prevents the database-level race, and the
isPendingguard prevents the UI-level double-fire.Fixes #366
This contribution was developed with AI assistance (Claude Code).
Summary by CodeRabbit