Clojure - кеширование с атомами? - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть несколько потоков, которым требуется доступ к коллекции значений, некоторые из этих значений также необходимо сохранить в базе данных при внесении в них каких-либо изменений, чтобы я не потерял состояние в случаеперезагрузка сервера и т. д.

В настоящее время я использую atom для хранения этих значений, у меня есть набор функций, которые я вызываю, когда что-то в atom необходимо изменить.

Внутри этих функций я также сохраняю данные в базе данных перед вызовом swap!, я выбрал этот подход, потому что мне нужно часто читать значения внутри атома, и он не выглядит производительным для open/close db connections каждый раз, когда меня интересует одно из значений.

вопрос:

Является ли этот подход жизнеспособным?Мне интересно знать, имел ли кто-нибудь успех в реализации подобного решения, или есть ли подводные камни, о которых мне следует знать?

1 Ответ

0 голосов
/ 21 сентября 2018

Атомы в порядке.

Альтернативным подходом было бы использование https://github.com/clojure/core.memoize или core.cached напрямую, как предложено Стефаном Кампхаузеном.

Подход:

  • Кэшировать результаты запросов на уровне функций.Таким образом, вы уверены, что вы получите именно то, как база данных вернет его, а не так, как вы думаете, что он будет сериализовать / десериализовать.
  • Неверный ключ / аргументы после того, как вы вставили / изменили что-то вбаза данных.

Одним из преимуществ этого подхода является то, что вы можете настроить поведение кэширования: 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"
  )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...