File tree 4 files changed +42
-14
lines changed
main/clojure/clojure/core/cache
test/clojure/clojure/core/cache
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
173
173
Change Log
174
174
====================
175
175
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.
176
178
* Release 1.1.234 on 2024-02-19
177
179
* Update parent pom and ` data.priority-map ` versions
178
180
* Release 1.0.225 on 2021-12-06
Original file line number Diff line number Diff line change 29
29
30
30
Reads from the current version of the atom."
31
31
([cache-atom e]
32
- (c/lookup @cache-atom e))
32
+ (force ( c/lookup @cache-atom e) ))
33
33
([cache-atom e not-found]
34
- (c/lookup @cache-atom e not-found)))
34
+ (force ( c/lookup @cache-atom e not-found) )))
35
35
36
36
(def ^{:private true } default-wrapper-fn #(%1 %2 ))
37
37
51
51
([cache-atom e wrap-fn value-fn]
52
52
(let [d-new-value (delay (wrap-fn value-fn e))]
53
53
(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))
56
59
e
57
- default-wrapper-fn
58
- (fn [_] @d-new-value))
59
- e
60
- ::expired )]
60
+ ::expired ))]
61
61
(when (< n 10 )
62
62
(if (= ::expired v)
63
63
(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))
66
69
e
67
- default-wrapper-fn
68
- (fn [_] @d-new-value))
69
- e
70
- ::expired ))
70
+ ::expired )))
71
71
v))))))
72
72
73
73
(defn has?
Original file line number Diff line number Diff line change 8
8
9
9
(ns clojure.core.cache.wrapped-test
10
10
(:require [clojure.core.cache.wrapped :as c]
11
+ [clojure.core.cache :as cache]
11
12
[clojure.test :refer [deftest is]]))
12
13
13
14
(deftest basic-wrapped-test
40
41
(recur (+ 1 n)))))
41
42
(println " ttl test completed" limit " calls in"
42
43
(- (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