<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent activity in core.cache</title>
<link>https://ask.clojure.org/index.php/activity/contrib-libs/core-cache</link>
<description></description>
<item>
<title>Closed: Could some calls to clojure.core/= be replaced by clojure.core/identical?</title>
<link>https://ask.clojure.org/index.php/12721/could-some-calls-clojure-core-replaced-clojure-core-identical?show=12721#q12721</link>
<description>&lt;p&gt;I'm using &lt;code&gt;core.cache&lt;/code&gt; in combination with &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/raxod502/lazy-map&quot;&gt;&lt;code&gt;LazyMap&lt;/code&gt;&lt;/a&gt;. Lazy maps are map-like objects (new data type encapsulating maps and adding some logic to auto-force delayed values associated with keys).&lt;/p&gt;
&lt;p&gt;When I started putting lazy maps as values of FIFO Cache I observed that all values are being realized just after the map lands in cache. After some digging I've found that it is caused by expression &lt;code&gt;(= ::expired v)&lt;/code&gt; in &lt;code&gt;clojure.core.cache.wrapped/lookup-or-miss&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;What happens is that &lt;code&gt;=&lt;/code&gt; internally calls &lt;code&gt;clojure.lang.Util/equiv&lt;/code&gt; (since &lt;code&gt;LazyMap&lt;/code&gt; implements &lt;code&gt;IPersistentCollection&lt;/code&gt;) and then, after some dispatching, &lt;code&gt;equiv&lt;/code&gt; is called to check whether the contents of a lazy map equals to other object (implicitly other map). This is the desired behavior and lazy map realizes all values to make comparison possible.&lt;/p&gt;
&lt;p&gt;However, when comparing a map-like object to something which is not a map (nor a collection), short-circuit would be welcome as soon as we know that it will for sure return &lt;code&gt;false&lt;/code&gt;. But changing that is probably more related to Clojure itself and things like &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.atlassian.net/browse/CLJ-1375&quot;&gt;CLJ-1375&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;What could be done on &lt;code&gt;core.cache&lt;/code&gt;'s side, if that's not too problematic, would be a replacement of&lt;/p&gt;
&lt;p&gt; &lt;code&gt;(= ::expired v)&lt;/code&gt; with &lt;code&gt;(identical? ::expired v)&lt;/code&gt;   &lt;/p&gt;
&lt;p&gt;in &lt;code&gt;clojure.core.cache.wrapped&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It would not only fix corner cases like mine but also speed things up a bit (explicit referential equality rocks when it comes to Clojure keywords).&lt;/p&gt;
&lt;p&gt;Other expressions where that could be changed (just in case) are:&lt;br&gt;
 &lt;code&gt;(= ::nope ret)&lt;/code&gt; and &lt;code&gt;(= ::nil v)&lt;/code&gt; from &lt;code&gt;clojure.core.cache&lt;/code&gt;.&lt;/p&gt;
</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12721/could-some-calls-clojure-core-replaced-clojure-core-identical?show=12721#q12721</guid>
<pubDate>Thu, 26 Feb 2026 17:09:09 +0000</pubDate>
</item>
<item>
<title>Closed: clojure.core.cache caches delays that hold exceptions as of version 1.2.254</title>
<link>https://ask.clojure.org/index.php/14965/clojure-core-cache-caches-delays-that-hold-exceptions-version?show=14965#q14965</link>
<description>&lt;p&gt;As of version 1.2.254 of &lt;code&gt;org.clojure/core.cache&lt;/code&gt;, using a &lt;code&gt;value-fn&lt;/code&gt; that throws will cause an entry to be added to the cache associated with a Delay with &lt;code&gt;:status :failed&lt;/code&gt; and the exception as a value.&lt;/p&gt;
&lt;p&gt;The code below can be used to compare the behavior between versions 1.1.234 and 1.2.254.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(require '[clojure.core.cache.wrapped :as cw])

(def counter (atom 0))

(defn value-fn [v]
  (prn :value-fn-called)
  (swap! counter inc)
  (if (= @counter 1)
    (throw (ex-info &quot;thrown&quot; {}))
    v))

(def test-cache (cw/lu-cache-factory {} :threshold 10))

(reset! counter 0)
; this will throw
(cw/lookup-or-miss test-cache &quot;throw&quot; value-fn)
; in 1.1.234 this will call value-fn again and not throw; in 1.2.254, it won't call and return
; the cached delay result, which is an exception
(cw/lookup-or-miss test-cache &quot;throw&quot; value-fn)

; evict to force call to value-fn
(cw/evict test-cache &quot;throw&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is related to work done in &lt;a rel=&quot;nofollow&quot; href=&quot;http://clojure.atlassian.net/browse/CCACHE-65&quot;&gt;CCACHE-65&lt;/a&gt; to avoid cache stampede in multi-threaded applications, and could be related to what has been reported in &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.atlassian.net/browse/CMEMOIZE-31&quot;&gt;CMEMOIZE-31&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This was initially reported &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojurians.slack.com/archives/C03S1KBA2/p1771873303347759&quot;&gt;in Clojurians Slack&lt;/a&gt;.&lt;/p&gt;
</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14965/clojure-core-cache-caches-delays-that-hold-exceptions-version?show=14965#q14965</guid>
<pubDate>Thu, 26 Feb 2026 02:49:10 +0000</pubDate>
</item>
<item>
<title>Commented: Multi-threaded cache stampede in core.cache</title>
<link>https://ask.clojure.org/index.php/12567/multi-threaded-cache-stampede-in-core-cache?show=14966#c14966</link>
<description>This (relatively new) behavior took as by surprise in one (probably quite niche) use case. We had been using 1.1.234 for a long time, and just upgraded to 1.2.254. &lt;br /&gt;
&lt;br /&gt;
Some of our unit tests[1] broke, because now doing a `get` on the (deref-ed) cache atom with a key wouldn't return the value associated with the key, but the delay that wrapped it. It took as a bit to realize what was going on.&lt;br /&gt;
&lt;br /&gt;
Nothing serious, just to let other people know in case the hit the same use case as we did.&lt;br /&gt;
&lt;br /&gt;
[1] In &lt;a href=&quot;https://github.com/gethop-dev/buddy-auth.jwt-oidc/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://github.com/gethop-dev/buddy-auth.jwt-oidc/&lt;/a&gt;</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12567/multi-threaded-cache-stampede-in-core-cache?show=14966#c14966</guid>
<pubDate>Mon, 23 Feb 2026 20:15:14 +0000</pubDate>
</item>
<item>
<title>Closed: Core Cache and Count</title>
<link>https://ask.clojure.org/index.php/14910/core-cache-and-count?show=14910#q14910</link>
<description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;I notice that in the wrapped namespace of core.cache, there is a &lt;strong&gt;has?&lt;/strong&gt; function that checks the wrapped cache if it has an element or not. It does this by delegating to the underlying cache &lt;strong&gt;c/has?&lt;/strong&gt; function of the wrapped cache.&lt;/p&gt;
&lt;p&gt;For reporting purposes, I need to get the current size of the cache (with the caveat of course that the size could be approximate, given the particular nature of a particular cache - but approximation is fine).&lt;/p&gt;
&lt;p&gt;Unfortuantely, a &lt;strong&gt;size&lt;/strong&gt; or &lt;strong&gt;count&lt;/strong&gt; function doesn't exist in the wrapped namespace, it only exists on the wrapped cache itself - thus doing:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(count @wrapped-cache)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt; does return the value. &lt;/p&gt;
&lt;p&gt;It would be good, however,  if there was also a similar function in the wrapped namespace, something like this (using &lt;strong&gt;size&lt;/strong&gt; as the function name, but could be something else):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn size
   [cache-atom]
   (c/count @cache-atom)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The rationale being that having this function exposed in the wrapped namespace keeps the code consistent - i.e., whilst I can continue to do:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(count @wrapped-cache)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It would more preferrable to keep using the wrapped namespace (as I do with other operations, such as evict), i.e., something along the lines of:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(wrapped/size wrapped-cache)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do you think this suggestion might be something that could be included in the wrapped namespace?&lt;/p&gt;
&lt;p&gt;Thank you.&lt;/p&gt;
&lt;p&gt;-=david=-&lt;/p&gt;
</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14910/core-cache-and-count?show=14910#q14910</guid>
<pubDate>Mon, 23 Feb 2026 15:06:07 +0000</pubDate>
</item>
<item>
<title>Commented: Is the clojure.cache behavior for lookup-or-miss value-fn re-entrancy broken or am I misunderstanding the docstring?</title>
<link>https://ask.clojure.org/index.php/14037/clojure-behavior-lookup-entrancy-misunderstanding-docstring?show=14685#c14685</link>
<description>This works, but it has the unfortunate side-effect of allowing errors into the cache.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
```clojure&lt;br /&gt;
;; Put an error in the cache with the default lookup-or-miss&lt;br /&gt;
(is (thrown? Exception&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(cache/lookup-or-miss cache-atom :wrapped (fn [_]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(throw (Exception. &amp;quot;oops&amp;quot;))))))&lt;br /&gt;
&lt;br /&gt;
;; Now we'll never get that error out of the cache&lt;br /&gt;
(is (thrown? Exception&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(cache/lookup-or-miss cache-atom :wrapped (fn [_] :ok)))))&lt;br /&gt;
```&lt;br /&gt;
&lt;br /&gt;
Here is a potential fix that removes errors from the cache:&lt;br /&gt;
&lt;br /&gt;
```clojure&lt;br /&gt;
(defn lookup-or-miss&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;quot;Retrieve the value associated with `e` if it exists, else compute the&lt;br /&gt;
&amp;nbsp;&amp;nbsp;value (using value-fn, and optionally wrap-fn), update the cache for `e`&lt;br /&gt;
&amp;nbsp;&amp;nbsp;and then perform the lookup again.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;value-fn (and wrap-fn) will only be called (at most) once even in the&lt;br /&gt;
&amp;nbsp;&amp;nbsp;case of retries, so there is no risk of cache stampede.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Since lookup can cause invalidation in some caches (such as TTL), we&lt;br /&gt;
&amp;nbsp;&amp;nbsp;trap that case and retry (a maximum of ten times).&amp;quot;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;([cache-atom e value-fn]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;(lookup-or-miss cache-atom e default-wrapper-fn value-fn))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;([cache-atom e wrap-fn value-fn]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;(let [d-new-value (delay (wrap-fn value-fn e))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;res (loop [n 0&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;v (c/lookup (swap! cache-atom&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c/through-cache&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;default-wrapper-fn&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn [_] d-new-value))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;::expired)]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(when (&amp;lt; n 10)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(if (= ::expired v)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(recur (inc n)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(c/lookup (swap! cache-atom&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;c/through-cache&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;default-wrapper-fn&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn [_] d-new-value))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;::expired))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;v)))]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(if (identical? res d-new-value)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(try&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(force res)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(catch Throwable t&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(swap! cache-atom&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(fn [a]&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(if (and (c/has? a e)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(identical? d-new-value (c/lookup a e)))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(c/evict a e)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a)))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(throw t)))&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(force res)))))&lt;br /&gt;
```</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14037/clojure-behavior-lookup-entrancy-misunderstanding-docstring?show=14685#c14685</guid>
<pubDate>Fri, 15 Aug 2025 22:55:47 +0000</pubDate>
</item>
<item>
<title>Commented: clojure.core.cache/TTLCache not extending TTL on hit?</title>
<link>https://ask.clojure.org/index.php/13584/clojure-core-cache-ttlcache-not-extending-ttl-on-hit?show=13586#c13586</link>
<description>Alright, I will just re-`assoc` on lookup (which is I am currently doing). Thanks for the reply and clarification!</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13584/clojure-core-cache-ttlcache-not-extending-ttl-on-hit?show=13586#c13586</guid>
<pubDate>Tue, 02 Jan 2024 17:24:54 +0000</pubDate>
</item>
<item>
<title>Closed: Suggest using (fn [&amp; args] x) over constantly in README.md</title>
<link>https://ask.clojure.org/index.php/12781/suggest-using-fn-args-x-over-constantly-in-readme-md?show=12781#q12781</link>
<description>&lt;p&gt;Was misled by the example in the README.md the other day. &lt;/p&gt;
&lt;p&gt;I did the equivalent of the following&lt;br&gt;
&lt;code&gt;(w/lookup-or-miss C3 :b (constantly (do (Thread/sleep 1000) 42)))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;instead of&lt;/p&gt;
&lt;p&gt;&lt;code&gt;(w/lookup-or-miss C3 :b (fn [&amp;amp; args] (do (Thread/sleep 1000) 42)))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Resulting in the IO call I was doing which takes the place of &lt;code&gt;(Thread/sleep 1000)&lt;/code&gt; to always be evaluated. This resulted in a &quot;cache&quot; that returns the value from the cache but will always trigger the call&lt;/p&gt;
</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12781/suggest-using-fn-args-x-over-constantly-in-readme-md?show=12781#q12781</guid>
<pubDate>Sat, 18 Mar 2023 22:53:00 +0000</pubDate>
</item>
<item>
<title>Commented: Docs for core.cache.documentation are ambigous</title>
<link>https://ask.clojure.org/index.php/12517/docs-for-core-cache-documentation-are-ambigous?show=12660#c12660</link>
<description>I've added some notes to the README (and to a couple of the /docs pages in the repo) to try to clarify the two styles of usage: &lt;a href=&quot;https://github.com/clojure/core.cache/blob/master/README.md&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://github.com/clojure/core.cache/blob/master/README.md&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
In particular, I changed the :as alias for clojure.core.cache.wrapped to w (from c) so it's clearer that the second block of examples all uses the wrapped API.</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12517/docs-for-core-cache-documentation-are-ambigous?show=12660#c12660</guid>
<pubDate>Sun, 12 Feb 2023 01:14:00 +0000</pubDate>
</item>
<item>
<title>Answer selected: Could there be a ClojureScript version of core.cache?</title>
<link>https://ask.clojure.org/index.php/12143/could-there-be-a-clojurescript-version-of-core-cache?show=12144#a12144</link>
<description>&lt;p&gt;I would personally welcome a plan for CLJS core.cache. I think that instead of reopening that tickets I 'd like to look at it from the perspective of CCACHE-55 and how we could design a library that works across langs.&lt;/p&gt;
</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12143/could-there-be-a-clojurescript-version-of-core-cache?show=12144#a12144</guid>
<pubDate>Sun, 04 Sep 2022 22:18:02 +0000</pubDate>
</item>
<item>
<title>Answered: Issues with LRU and LU cache in core.cache</title>
<link>https://ask.clojure.org/index.php/10849/issues-with-lru-and-lu-cache-in-core-cache?show=10853#a10853</link>
<description>&lt;p&gt;I would certainly be willing to accept a patch. I will look into getting you Jira access today.&lt;/p&gt;
&lt;p&gt;As for the tie-breakers I need to look at the code again to reload context but I suspect that comment is unnecessary and should be removed.&lt;/p&gt;
</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10849/issues-with-lru-and-lu-cache-in-core-cache?show=10853#a10853</guid>
<pubDate>Tue, 27 Jul 2021 13:08:32 +0000</pubDate>
</item>
<item>
<title>Commented: Why do core.cache's deftypes not implement equality?</title>
<link>https://ask.clojure.org/index.php/10370/why-do-core-caches-deftypes-not-implement-equality?show=10379#c10379</link>
<description>Thank you! These are useful insights.&lt;br /&gt;
&lt;br /&gt;
Accordingly I ended up implementing a thin wrapper for ensuring that one uses the right methods and only can access the underlying data in a safe way.&lt;br /&gt;
&lt;br /&gt;
Merely as an observation, I wonder if changing deftype-&amp;gt;defrecord would have helped here?</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10370/why-do-core-caches-deftypes-not-implement-equality?show=10379#c10379</guid>
<pubDate>Fri, 26 Mar 2021 12:19:10 +0000</pubDate>
</item>
<item>
<title>Commented: core.cache: TTLCacheQ timer is not monotonic</title>
<link>https://ask.clojure.org/index.php/10306/core-cache-ttlcacheq-timer-is-not-monotonic?show=10333#c10333</link>
<description>Thanks, John. I'll have a read through all of this when I go back to working on core.cache next.</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10306/core-cache-ttlcacheq-timer-is-not-monotonic?show=10333#c10333</guid>
<pubDate>Sat, 13 Mar 2021 03:57:19 +0000</pubDate>
</item>
<item>
<title>Answered: Suggested usage subject to Cache Stampede</title>
<link>https://ask.clojure.org/index.php/674/suggested-usage-subject-to-cache-stampede?show=8470#a8470</link>
<description>&lt;p&gt;This is fixed in &lt;code&gt;org.clojure/core.cache&lt;/code&gt; &quot;0.8.1&quot; with the addition of the &lt;code&gt;clojure.core.cache.wrapped&lt;/code&gt; namespace and, in particular, the new &lt;code&gt;lookup-or-miss&lt;/code&gt; function in that namespace.&lt;/p&gt;
</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/674/suggested-usage-subject-to-cache-stampede?show=8470#a8470</guid>
<pubDate>Tue, 27 Aug 2019 20:41:52 +0000</pubDate>
</item>
<item>
<title>Answered: Add ARC or CAR algorithm</title>
<link>https://ask.clojure.org/index.php/666/add-arc-or-car-algorithm?show=675#a675</link>
<description>Reference: &lt;a href=&quot;https://clojure.atlassian.net/browse/CCACHE-38&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://clojure.atlassian.net/browse/CCACHE-38&lt;/a&gt; (reported by desk@danielcompton.net)</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/666/add-arc-or-car-algorithm?show=675#a675</guid>
<pubDate>Wed, 26 Jun 2019 12:00:00 +0000</pubDate>
</item>
<item>
<title>Answered: Add weak-cache</title>
<link>https://ask.clojure.org/index.php/667/add-weak-cache?show=677#a677</link>
<description>Reference: &lt;a href=&quot;https://clojure.atlassian.net/browse/CCACHE-35&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://clojure.atlassian.net/browse/CCACHE-35&lt;/a&gt; (reported by alex+import)</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/667/add-weak-cache?show=677#a677</guid>
<pubDate>Wed, 26 Jun 2019 12:00:00 +0000</pubDate>
</item>
<item>
<title>Answered: Stats for cache</title>
<link>https://ask.clojure.org/index.php/668/stats-for-cache?show=679#a679</link>
<description>Reference: &lt;a href=&quot;https://clojure.atlassian.net/browse/CCACHE-51&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://clojure.atlassian.net/browse/CCACHE-51&lt;/a&gt; (reported by akhomchenko)</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/668/stats-for-cache?show=679#a679</guid>
<pubDate>Wed, 26 Jun 2019 12:00:00 +0000</pubDate>
</item>
<item>
<title>Answered: Add eviction implementation to LIRSCache</title>
<link>https://ask.clojure.org/index.php/669/add-eviction-implementation-to-lirscache?show=689#a689</link>
<description>Reference: &lt;a href=&quot;https://clojure.atlassian.net/browse/CCACHE-11&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://clojure.atlassian.net/browse/CCACHE-11&lt;/a&gt; (reported by fogus)</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/669/add-eviction-implementation-to-lirscache?show=689#a689</guid>
<pubDate>Wed, 26 Jun 2019 12:00:00 +0000</pubDate>
</item>
<item>
<title>Answered: Create function backed cache</title>
<link>https://ask.clojure.org/index.php/670/create-function-backed-cache?show=690#a690</link>
<description>Reference: &lt;a href=&quot;https://clojure.atlassian.net/browse/CCACHE-17&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://clojure.atlassian.net/browse/CCACHE-17&lt;/a&gt; (reported by fogus)</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/670/create-function-backed-cache?show=690#a690</guid>
<pubDate>Wed, 26 Jun 2019 12:00:00 +0000</pubDate>
</item>
<item>
<title>Answered: LIRSCache defect allows it's memory use to grow without bound</title>
<link>https://ask.clojure.org/index.php/671/lirscache-defect-allows-its-memory-use-to-grow-without-bound?show=694#a694</link>
<description>Reference: &lt;a href=&quot;https://clojure.atlassian.net/browse/CCACHE-32&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://clojure.atlassian.net/browse/CCACHE-32&lt;/a&gt; (reported by alex+import)</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/671/lirscache-defect-allows-its-memory-use-to-grow-without-bound?show=694#a694</guid>
<pubDate>Wed, 26 Jun 2019 12:00:00 +0000</pubDate>
</item>
<item>
<title>Answered: Benchmark v0.5.x against Google Guava</title>
<link>https://ask.clojure.org/index.php/672/benchmark-v0-5-x-against-google-guava?show=695#a695</link>
<description>Reference: &lt;a href=&quot;https://clojure.atlassian.net/browse/CCACHE-16&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://clojure.atlassian.net/browse/CCACHE-16&lt;/a&gt; (reported by fogus)</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/672/benchmark-v0-5-x-against-google-guava?show=695#a695</guid>
<pubDate>Wed, 26 Jun 2019 12:00:00 +0000</pubDate>
</item>
<item>
<title>Answered: Split protocols from implementations</title>
<link>https://ask.clojure.org/index.php/673/split-protocols-from-implementations?show=696#a696</link>
<description>Reference: &lt;a href=&quot;https://clojure.atlassian.net/browse/CCACHE-55&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https://clojure.atlassian.net/browse/CCACHE-55&lt;/a&gt; (reported by arichiardi)</description>
<category>core.cache</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/673/split-protocols-from-implementations?show=696#a696</guid>
<pubDate>Wed, 26 Jun 2019 12:00:00 +0000</pubDate>
</item>
</channel>
</rss>