core.memoize can run the memoized function twice

Description

core.memoize has a race condition in its delay, so two threads that try to call a memoized function with identical args at the same time can cause the function to be run twice.

(def mf (memo/lru (fn [x] (prn x) x)))
(future (mf 1))
(future (mf 1))
;; can print:
;; 1
;; 1

core.memoize is often used to reduce e.g. network load by caching slow queries, and in that case this race condition is very bad. If you make two slow network queries at once, you get no memoization!

This was noted by Jozef Wagner in CMEMOIZE-8, but it still has not been fixed.

I have provided a patch that prevents this race condition, based on his recommended fix. I included a test to demonstrate the bug.

Environment

None

Assignee

Alex Miller

Reporter

Leon Barrett

Labels

None

Approval

None

Patch

Code and Test

Priority

Major
Configure