core.cache

Suggested usage subject to Cache Stampede

Details

  • Type: Defect Defect
  • Status: Open Open
  • Priority: Major Major
  • Resolution: Unresolved
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None

Description

I've been trying to wrap my head around core.cache, and it seems to me that the suggest use in the documentation, i.e.

(defn get-data [key]
  (cache/lookup (swap! cache-store
                       #(if (cache/has? % key)
                          (cache/hit % key)
                          (cache/miss % key (retrieve-data key))))
                key))

will result in a Cache Stampede since (retrieve-data key) might be called multiple times if swap! retries due to compare-and-swap misses. Unfortunately I don't have a suggestion on how this could be fixed.

Activity

Hide
Sean Corfield added a comment -

It took me a while to find this suggested usage – https://github.com/clojure/core.cache/wiki/Using

I should update that to use through-cache which is more idiomatic now:

(defn get-data [key]
  (cache/lookup (swap! cache-store cache/through-cache key retrieve-data) key))

It would still suffer from the same possibility of Cache Stampede but at least it would be consistent with the newer API.

I suspect using a local delay would mitigate the stampede issue but it would make for very ugly code and it would not play well with through-cache – so I'll have to give that some thought.

Show
Sean Corfield added a comment - It took me a while to find this suggested usage – https://github.com/clojure/core.cache/wiki/Using I should update that to use through-cache which is more idiomatic now:
(defn get-data [key]
  (cache/lookup (swap! cache-store cache/through-cache key retrieve-data) key))
It would still suffer from the same possibility of Cache Stampede but at least it would be consistent with the newer API. I suspect using a local delay would mitigate the stampede issue but it would make for very ugly code and it would not play well with through-cache – so I'll have to give that some thought.
Hide
Sean Corfield added a comment -

The local delay version would look like this:

(defn get-data [key]
  (let [data (delay (retrieve-data key)]
    (cache/lookup (swap! cache-store cache/through-cache key (fn [_] @data)) key)))
Show
Sean Corfield added a comment - The local delay version would look like this:
(defn get-data [key]
  (let [data (delay (retrieve-data key)]
    (cache/lookup (swap! cache-store cache/through-cache key (fn [_] @data)) key)))

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated: