Fork me on GitHub
#clojure
<
2018-11-03
>
eriktjacobsen01:11:45

I'm following along the LRU clojure.core.cache guide which yields

(defn get-data [key]
  (cache/lookup (swap! cache-store
                       #(if (cache/has? % key)
                          (cache/hit % key)
                          (cache/miss % key (retrieve-data key))))
                key))
However, if retrieve-data ever ends up using the same cache, then you get into a situation where inside that swap!, when cache/hit is called it modifies the underlying cache, which causes the swap! to be re-run, which causes another hit, and so on causing an infinite loop. Other than going through code paths to manually make sure you never end up with nested cache calls, is there a clever workaround for this? I don't really care about incrementing the LRU counter for sub-queries, so perhaps re-binding the cache lookup to skip using cache/hit? that seems really messy and probably not thread-safe....

eriktjacobsen01:11:08

It's also 7pm on a friday, perhaps just needs hammock time 😉

seancorfield03:11:50

@eriktjacobsen This sounds like a variant of the "cache stampede" issue that someone raised a JIRA ticket about...

seancorfield03:11:12

I suggested this as a workaround

(defn get-data [key]
  (let [data (delay (retrieve-data key)]
    (cache/lookup (swap! cache-store cache/through-cache key (fn [_] @data)) key)))
since at least retrieve-data will only be called once, even it cache/through-cache ends up calling the fn more than once.

seancorfield03:11:56

I'm thinking this needs to be baked into the library as a higher-level operation...

seancorfield03:11:14

I'm also looking at ways to avoid the weird edge case you can get with certain caches where the enclosed has? succeeds but the hit function evicts the item, and then the outside lookup returns nil -- which is surprising at best and annoying at worst.

eriktjacobsen04:11:11

Thanks so much @seancorfield, yes a local delay will work well in this case. Good to know about the has?-evict situation.

Audrius11:11:20

what is the equivalent of (.mkdir (java.io.File. "/tmp/crawl/")) on windows?

valtteri13:11:22

What is equivalent of lein deps with clj and deps.edn? I want to resolve and download dependencies but not run anything (yet).

bronsa13:11:32

clj -Sforce < /dev/null

valtteri13:11:47

Thanks, it works!

hoynk17:11:05

Is there a way to mark a test as pending in clojure.test ?

kenny17:11:31

In clojure.data.json, is there a way to have a default function be called if the object type isn't support? e.g. I simply want to call the .toString method on an object if no built-in JSON encoder is found.

cddr17:11:17

@kenny you could maybe make a function that checks for whether a value implements the JsonWriter protocol and give it to the :value-fn option in clojure.data.json/write-str

andy.fingerhut17:11:20

@boccato By pending, do you mean you expect it to fail right now, but still want it to run and show up in the results as "N tests were run, A passed, B passed but were expected to fail, C failed but were not expected to" ?

andy.fingerhut18:11:16

I am not aware of any feature clojure.test provides to do that, but I haven't even read through all of its docs, so could be ignorant of it. Hopefully someone else will chime in with more info there. @plexus is working on a tool for Clojure testing in the next few months, funded by Clojurists Together. There is an article of what he is planning to do, and a link to contact him at the bottom of the article, here: https://lambdaisland.com/blog/2018-11-02-test-wars-new-hope