File tree Expand file tree Collapse file tree 4 files changed +42
-14
lines changed
main/clojure/clojure/core/cache
test/clojure/clojure/core/cache Expand file tree Collapse file tree 4 files changed +42
-14
lines changed Original file line number Diff line number Diff line change 1+ {:lint-as {clojure.core.cache/defcache clojure.core/defrecord}}
Original file line number Diff line number Diff line change @@ -173,6 +173,8 @@ Developer Information
173173Change Log
174174====================
175175
176+ * Release 1.2.next in progress
177+ * [ CCACHE-65] ( http://clojure.atlassian.net/browse/CCACHE-65 ) Use ` delay ` in ` lookup-or-miss ` to avoid cache-stampede.
176178* Release 1.1.234 on 2024-02-19
177179 * Update parent pom and ` data.priority-map ` versions
178180* Release 1.0.225 on 2021-12-06
Original file line number Diff line number Diff line change 2929
3030 Reads from the current version of the atom."
3131 ([cache-atom e]
32- (c/lookup @cache-atom e))
32+ (force ( c/lookup @cache-atom e) ))
3333 ([cache-atom e not-found]
34- (c/lookup @cache-atom e not-found)))
34+ (force ( c/lookup @cache-atom e not-found) )))
3535
3636(def ^{:private true } default-wrapper-fn #(%1 %2 ))
3737
5151 ([cache-atom e wrap-fn value-fn]
5252 (let [d-new-value (delay (wrap-fn value-fn e))]
5353 (loop [n 0
54- v (c/lookup (swap! cache-atom
55- c/through-cache
54+ v (force (c/lookup (swap! cache-atom
55+ c/through-cache
56+ e
57+ default-wrapper-fn
58+ (fn [_] d-new-value))
5659 e
57- default-wrapper-fn
58- (fn [_] @d-new-value))
59- e
60- ::expired )]
60+ ::expired ))]
6161 (when (< n 10 )
6262 (if (= ::expired v)
6363 (recur (inc n)
64- (c/lookup (swap! cache-atom
65- c/through-cache
64+ (force (c/lookup (swap! cache-atom
65+ c/through-cache
66+ e
67+ default-wrapper-fn
68+ (fn [_] d-new-value))
6669 e
67- default-wrapper-fn
68- (fn [_] @d-new-value))
69- e
70- ::expired ))
70+ ::expired )))
7171 v))))))
7272
7373(defn has?
Original file line number Diff line number Diff line change 88
99(ns clojure.core.cache.wrapped-test
1010 (:require [clojure.core.cache.wrapped :as c]
11+ [clojure.core.cache :as cache]
1112 [clojure.test :refer [deftest is]]))
1213
1314(deftest basic-wrapped-test
4041 (recur (+ 1 n)))))
4142 (println " ttl test completed" limit " calls in"
4243 (- (System/currentTimeMillis ) start) " ms" )))
44+
45+ (deftest cache-stampede
46+ (let [thread-count 100
47+ cache-atom (-> {}
48+ (cache/ttl-cache-factory :ttl 120000 )
49+ (cache/lu-cache-factory :threshold 100 )
50+ (atom ))
51+ latch (java.util.concurrent.CountDownLatch. thread-count)
52+ invocations-counter (atom 0 )
53+ values (atom [])]
54+ (dotimes [_ thread-count]
55+ (.start (Thread. (fn []
56+ (swap! values conj
57+ (c/lookup-or-miss cache-atom " my-key"
58+ (fn [_]
59+ (swap! invocations-counter inc)
60+ (Thread/sleep 3000 )
61+ " some value" )))
62+ (.countDown latch)))))
63+
64+ (.await latch)
65+ (is (= 1 (deref invocations-counter)))
66+ (doseq [v @values]
67+ (is (= " some value" v)))))
You can’t perform that action at this time.
0 commit comments