This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-01-26
Channels
- # beginners (55)
- # bristol-clojurians (4)
- # calva (9)
- # clj-kondo (29)
- # cljsrn (1)
- # clojars (6)
- # clojure (57)
- # clojure-dev (4)
- # clojure-uk (22)
- # clojurescript (52)
- # code-reviews (1)
- # core-async (33)
- # cursive (12)
- # datomic (46)
- # docker (7)
- # figwheel-main (13)
- # fulcro (8)
- # graalvm (3)
- # instaparse (1)
- # kaocha (2)
- # perun (1)
- # portkey (5)
- # re-frame (3)
- # shadow-cljs (46)
- # spacemacs (7)
- # specter (3)
- # vim (1)
- # vscode (3)
Hi, I’m struggling with a bug. I’ve tried to make a minimal example of the code.
When running this code I can see from the tap>
that sometimes cache
resets to an empty map {}
. Anyone have an idea what I’m doing wrong?
(let [in (chan)
tags [:some :list :of :tags]
f some-function]
(go-loop [cache {}]
(let [{:keys [tag payload]} (<! in)
new-cache (assoc cache tag payload)
result (apply f (for [tag tags] (get new-cache tag)))]
(tap> {:cache cache
:new-cache new-cache
:result result})
(recur new-cache)))
in)
Have you restarted your repl recently? My guess is you have some other code running, maybe an earlier version of that loop
@hiredman have restarted many times since finding this bug. Pretty sure that’s not the problem
It kind of has to be. What did does that tap result look like that is making you thing cache is becoming {}
?
Are you seeing {}
in that tap output and concluding that cache has become {}
when in fact that would be {:cache {} :new-cache ... :new-result ...}
?
Are you sure you are looking at the correct file? I've seen people edit one copy and run another. Are you sure you are saving the file after edits?
You can put an (assert nil)
at the top of the loop to determine if that code is actually being run, and an (assert (not-empty? new-cache))
later on in the loop to determine if that loop is the source of those tap messages
If you are telling your editor to eval the file, it may load the file from disk instead of the contents of the unsaved buffer
I’m using chlorine and it’s command to evaluate a specific form. But I will try your suggestions to make sure I’m looking at the right code.
The assert nil will cause an error if the code you are looking at is actually run, then you can remove it, and then the asset not empty will fire if new cache ever does become empty in that code
Does chlorine just keep a repl around and opening and closing the repl window or whatever just reconnects you to it?
If you actual code is building the cache with something more complicated then assoc the problem is likely there
The only thing thats missing from my example is that i put (`>!`) result
on some channels
In the example code, cache only grows in size, which is kind of atypical for a cache, is there any code at all that removes or expires entries
The number of tags is indeed constant. It just takes the most recent value with the tag, assocs it into the cache and reruns the function f using all the values in the cache.
I can't debug it without more information, either more detail of the real code, or the results of the asserts I suggested. I strongly recommend finding your invariants like new cache is always greater than or equal to cache in size, and asserting it in as many places as possible in code you are debugging