fix(task-history): route invalidate() and invalidateAll() through withLock#912
Conversation
|
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 (3)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughTask history invalidation now runs through the write lock. ChangesTask history cache consistency
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ 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 |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
edelauna
left a comment
There was a problem hiding this comment.
Nice! Thanks for taking this on!
Two items that don't map to diff lines:
webviewMessageHandler.ts:966 — invalidateAll() is now async but is called without await. Any error it throws is silently swallowed, and a reader can't tell whether the cache clear is guaranteed to finish before the subsequent reconcile(). Consider await provider.taskHistoryStore.invalidateAll() there.
Missing lock-contention test for invalidate() — the PR wraps both invalidate() and invalidateAll() in withLock, but only invalidateAll() gets a concurrency regression test. If someone removed withLock from invalidate() in a future refactor, nothing would catch it. A parallel test modelled on the new invalidateAll() one (gate writeTaskFile, call store.invalidate(id) concurrently, assert cache reflects the written value) would close the gap.
| } | ||
|
|
||
| /** | ||
| * Clear all in-memory cache and reload from index. |
There was a problem hiding this comment.
The JSDoc still says "reload from index" but the body only calls cache.clear() -- loadIndex() is never called. Worth updating to reflect the actual behavior?
|
Updated the handler to await |
edelauna
left a comment
There was a problem hiding this comment.
Thanks so much for your contribution!
|
I did open a related issue: #949 which I noticed during review - if this is something you would like to help out with next 🙏 |
Locks
invalidate()andinvalidateAll()behindTaskHistoryStore's existingwithLockqueue so cache invalidation cannot interleave with an in-flight mutation. Each method keeps its existing cache behavior.Related GitHub Issue
Fixes #698
Description
Per your note, I routed
invalidate()rather than removing it: the census found no non-test callers, butTaskHistoryStoreis exported from the task-persistence barrel, so deleting its public method could break consumers.invalidate()TaskHistoryStorewithLockinvalidateAll()TaskHistoryStorewithLockTest Procedure
The regression blocks
writeTaskFilewith a manually controlled promise after the lock is acquired, callsinvalidateAll(), then releases the write. It asserts thatonWritesees both cached tasks before the queued invalidation clears the final cache, so no timer or scheduling delay controls the result.pnpm --filter zoo-code exec vitest run core/task-persistence/__tests__/TaskHistoryStore.spec.tspnpm testpnpm lintpnpm check-typesPre-Submission Checklist
Additional Notes
Non-goals: no other cache methods, lock implementation, callers, or APIs are changed.
Summary by CodeRabbit