Skip to content

Instantly share code, notes, and snippets.

@rwat
Last active June 28, 2017 16:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rwat/4abcebcb4cfae956f382 to your computer and use it in GitHub Desktop.
Save rwat/4abcebcb4cfae956f382 to your computer and use it in GitHub Desktop.
generalizes and makes transparent the use of clojure.core.cache
(ns foo
(:require [clojure.core.cache :as cache]))
(defn cache-interact
[the-agent the-function & the-items]
"Generalizes the interaction of performing c.c.cache operations by
transparently retrieving something from a cache or running the supplied
function outside of the agent's thread to generate a value"
(let [delay-func (delay (apply the-function the-items))
the-promise (promise)
agent-fn (fn [cache- d p & xs]
(let [x (first xs)]
(if (cache/has? cache- x)
(do
(deliver p (get cache- x))
(cache/hit cache- x))
(do
(deliver p d)
(cache/miss cache- x d)))))]
(apply send the-agent agent-fn delay-func the-promise the-items)
@@the-promise))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(comment
(let [c (agent (cache/lirs-cache-factory {} :threshold 100))
f (fn [x] (do (Thread/sleep 1000) {x (identity x)}))]
(cache-interact c f :x)
(cache-interact c f :y)
(cache-interact c f :x))
=> {:x :x}
)
@jeroenvandijk
Copy link

Thanks for the inspiration! After thinking about it a bit I wonder what you think of the following version:

(defn with-cache [cache-atom f & args]
  (let [cache-key [f args]
        delayed (delay (apply f args))
        cache-after (swap! cache-atom (fn cache-updater [cache-before]
                                        (if (cache/has? cache-before cache-key)
                                            (cache/hit cache-before cache-key)
                                            (cache/miss cache-before cache-key delayed))))]
    @(cache/lookup cache-after cache-key)))

It doesn't need the promises and seems more simple.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment