Repository navigation
fix(core): make Util.memoize thread-safe - #1406
Conversation
Util.memoize stored its cached value and "computed" flag in plain fields, so a thread racing the first call could observe the flag set without the value and get null back, and concurrent callers could each re-run the delegate. The memoizer backs function keys and anchors, the ExtensionCollection lookup maps, and relation record types, so a shared ExtensionCollection failed intermittently on first concurrent use with "NullPointerException: key" or "Duplicate key null". The flag is now volatile and initialization uses double-checked locking, so the delegate runs exactly once and every caller sees the fully computed value. The memoizer's delegate and AbstractRel's memoizer field are now final so they are safely published along with their owner. Closes substrait-io#1389
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (3)
Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review. 📝 SummarySummary by CodeRabbit
Walkthrough
ChangesMemoized supplier
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~12 minutes Change: Bug fix · Severity of issue fixed: Medium Merge Risk: ⚪ Minimal · up to No actionable issue remains; the change is ready to merge after normal checks. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)✅ Passed checks (4 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 |
Util.memoize stored its cached value and "computed" flag in plain
fields, so a thread racing the first call could observe the flag set
without the value and get null back, and concurrent callers could each
re-run the delegate. The memoizer backs function keys and anchors, the
ExtensionCollection lookup maps, and relation record types, so a shared
ExtensionCollection failed intermittently on first concurrent use with
"NullPointerException: key" or "Duplicate key null".
The flag is now volatile and initialization uses double-checked locking,
so the delegate runs exactly once and every caller sees the fully
computed value. The memoizer's delegate and AbstractRel's memoizer field
are now final so they are safely published along with their owner.
Closes #1389