欢迎!请查阅 关于 页面以了解更多有关此功能的信息。
我一直在试图了解 core.cache,我发现文档中推荐的用法,比如
`(defn get-data [key](cache/lookup (swap! cache-store
`
#(if (cache/has? % key) (cache/hit % key) (cache/miss % key (retrieve-data key)))) key))
将导致(链接:https://en.wikipedia.org/wiki/Cache_stampede 文本:缓存涌入),因为如果由于比较和交换失败而重新尝试 swap!,则可能多次调用 {{(retrieve-data key)}}。遗憾的是,我没有提出任何关于如何修复此问题的建议。
swap!
这已在 org.clojure/core.cache "0.8.1" 中修复,添加了 clojure.core.cache.wrapped 命名空间,并在该命名空间中特别添加了新的 lookup-or-miss 函数。
org.clojure/core.cache
clojure.core.cache.wrapped
lookup-or-miss
评论者:seancorfield
花费了一些时间我找到了这个推荐的用法 – https://github.com/clojure/core.cache/wiki/Using
我应该更新为使用 {{through-cache}},现在更具表达性
(defn get-data [key] (cache/lookup (swap! cache-store cache/through-cache key retrieve-data) key))
这仍然有可能出现缓存涌入的问题,但至少在较新的 API 中保持了一致性。
我认为使用本地 {{delay}} 可以缓解猛冲问题,但它会导致代码看起来非常丑陋,并且与 {{through-cache}} 不匹配,所以我需要考虑一下。
本地 {{delay}} 版本将如下所示
`(defn get-data [key](let [data (delay (retrieve-data key)]
(cache/lookup (swap! cache-store cache/through-cache key (fn [_] @data)) key)))