Clojure-缓存原子?

时间:2018-09-21 10:52:04

标签: clojure

我有许多线程需要访问值的集合,对它们进行任何更改时,其中一些值也需要持久保存到数据库中,以免在出现以下情况时不会丢失状态服务器重启等。

当前,我正在使用atom存储这些值,当需要更改atom中的某些内容时,我会调用一组函数。

在这些函数中,我还要在调用swap!之前将数据持久保存到数据库中,所以我选择了这种方法,因为我需要经常读取原子内部的值,并且对{{1 }}每当我对其中一个值感兴趣时。

问题:

这种方法可行吗?我想知道是否有人成功实现了类似的解决方案,还是我应该意识到的陷阱?

1 个答案:

答案 0 :(得分:0)

原子很好。

另一种方法是直接使用https://github.com/clojure/core.memoize或core.cached,如Stefan Kamphausen所建议的那样。

方法:

  • 在功能级别上缓存查询结果。这样,您可以确定返回的内容正是数据库将如何返回它,而不是您认为它将进行序列化/反序列化的方式。
  • 在数据库中插入/更改某些内容后,使密钥/参数无效。

此方法的一个好处是您可以调整缓存行为:TTL,LRU,FIFO等。

演示:

(require '[clojure.core.memoize :as memo])

;; suppose this is a real DB
(def db (atom {}))

(defn my-get [k]
  ;; expensive database call
  (Thread/sleep 5000)
  (get @db k))

(def my-get-cached
  (memo/memo my-get))

(defn my-put
  [k val]
  (swap! db assoc k val)
  (memo/memo-clear! my-get-cached [k]))

(comment
  (my-put :foo "the value")
  (my-get-cached :foo) ;; wait 5 seconds, "the value"
  (my-get-cached :foo) ;; "the value", instantly
  (my-put :bar "other-value")
  (my-get-cached :foo) ;; "the value", still instantly
  (my-get-cached :bar) ;; wait 5 seconds, "other value"
  (my-put :foo "changed")
  (my-get-cached :foo) ;; wait 5 seconds, "changed"
  )