Fork me on GitHub
#core-async
<
2018-09-29
>
orestis19:09:06

So I was trying to observe contention over swap!ing an atom via 1000 futures/threads, and naturally when using println you get hilarious and useless results. I then thought to make a huge core.async channel (e.g. with a 10000 long buffer) to serialize printing, thinking that there would be no locks to muck up my observations, but it seems there is some fishy behaviour going on there.

orestis19:09:36

(def print-chan (a/chan 100000))

(defn aprintln [& args]
  (a/put! print-chan args))

(aprintln "hello " "from" " chan")

(a/go-loop []
  (apply println (a/<! print-chan))
  (recur))

orestis19:09:35

This is working as expected, but combined with:

(defn up! [x]
  (let [t (Thread/currentThread)]
    (aprintln "attempting to increment:" x " from " t " id " (.getId t))
    (inc x)))

(doseq [x (range 1000)]
  (future (swap! thingy up!)))
I see thingy which is an atom, only go up to ~800, whereas of course it should be 1000.

orestis19:09:06

Removing the aprintln function results in a nice smooth 1000 result which is as expected. I wondering if I’ve not understood the semantics of the the go-loop or the put!?

orestis19:09:48

Ooh, put! calls a function on the calling thread after the put! succeeds, I wonder if there’s something there?