Skip to content

Instantly share code, notes, and snippets.

@rwat rwat/cache-interact.clj
Last active Jun 28, 2017

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

jeroenvandijk commented Nov 25, 2016

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
You can’t perform that action at this time.