fix(store): prevent batch race condition causing silent state loss in nested batches#1663
Conversation
… nested batches Add epoch guard to batch microtask dispatch to prevent stale notifications when a new batch starts before the previous microtask fires. Fix mutate() inside batches to update both commit and rollback closures so error recovery restores the correct pre-batch state. Closes Karanjot786#1658
|
Hi @atul-upadhyay-7 👋 ⭐ Star this repo before your PR merges. Why? GSSoC 2026 contributors who star get priority review and points credit. After you star, push any commit (or re-run this check). The Thanks for your contribution to TermUI. |
There was a problem hiding this comment.
🎉 Thanks for your first PR to TermUI, @atul-upadhyay-7.
Before your PR merges:
- ⭐ Star the repo. Required. The
star-checkjob blocks your merge otherwise. - ✅ All checks green:
build,test,typecheck. - 🏷 PR title follows
type: short description. Example:fix: handle empty list. - 🔗 Link your closing issue in the description.
GSSoC 2026 points come from labels after merge:
gssoc:approved. +50 base points.level:beginner/intermediate/advanced/critical. +20 / +35 / +55 / +80.quality:clean/exceptional. x 1.2 / x 1.5.type:*. Stackable bonus.
Your reviewer responds within 48 hours. Ping @Karanjot786 on Discord for urgent help.
🚀 Welcome to the cohort.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthrough
ChangesBatch epoch tracking and microtask staleness prevention
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
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
Fixes a critical race condition in
@termuijs/store'sbatch()mechanism where nested batch calls could silently lose intermediate state mutations, and where a stale microtask could dispatch notifications for the wrong batch.Closes #1658
Changes
1. Epoch guard for microtask dispatch
Added
_batchEpochcounter that increments when an outermost batch starts.flushBatch()snapshots the epoch before scheduling the microtask. If a new batch starts before the microtask fires, the epoch will have changed and the stale microtask bails out without dispatching.Before: Two consecutive batches could both dispatch, with the first microtask reading the second batch's entries.
After: The first microtask detects the epoch mismatch and skips dispatch.
2.
mutate()updates rollback closure in existing batch entriesWhen
mutate()found an existing batch entry, it only updatedexisting.nextState-- thecommitandrollbackclosures were never updated. This meant:nextStateAfter: Both
commitandrollbackclosures are updated when an existing entry is found.3. Cleanup: removed unused
prevStatedestructuring in error pathThe
flushBatch(true)path destructuredprevStatebut never used it.Tests added
setStatesurvives innersetStatemutate()+setState()coalesce properlymutate()calls produce one notificationmutate()rolls back completelyVerification
Summary by CodeRabbit
Bug Fixes
Tests