原子设置并获取 clojure.core.cache



我目前正在玩弄clojure.core.cache,当存储在Atom中的缓存中有缓存未命中时,我无法弄清楚如何对它进行原子设置和获取操作。

我正在尝试将基于时间的缓存引入我的 clojure 服务,一方面减少昂贵的数据库调用量,另一方面如果我只使用memoize,则避免将来某个时间内存溢出(因为这应该是一个长时间运行的服务(。

现在在我看来,使用该库的正确方法是通过工厂函数之一创建一个缓存,将其存储在原子中,然后在我们更新它时交换新缓存。(请参阅下面的文档示例(


(require '[clojure.core.cache :as cache])
(def cache (atom (cache/fifo-cache-factory {:a 1, :b 2})))
(swap! cache cache/through-cache :d (constantly 13))
;=> {:a 1, :b 3, :d 13}
(swap! cache cache/evict :b)
;=> {:a 1, :d 13}
(get @cache :a)
;=> 1

现在我不明白的是如何进行原子设置和获取操作,即如何在必要时检索值和透明填充的缓存。

如果我通过 2 个操作执行此操作,根据我的理解,可能会导致竞争条件,因此在生产中使用是不安全的。

我错过了什么吗?

另外:我现在意识到获取和设置操作cache/through是以原子方式完成的,因此每个get操作都将返回相同的值。

Atoms 保证不会有竞争条件。

每次调用swap!都在后台使用 CAS 操作。这就是为什么您需要在swap!中提供的函数应该是无副作用的,因为如果另一个线程妨碍了更新原子,它可能会重试。

swap!中检索和填充through-cache是正确的方法,也就是说,如果您需要保证对值的慢速检索操作只执行一次,您可能需要查看agents

请参阅 https://clojure.org/reference/agents 尤其是这部分: "如果在函数执行期间(直接或间接(进行了任何其他调度,它们将被保留,直到代理的状态被更改。

最新更新