core-async

niveauverleih 2020-06-30T14:15:54.015100Z

I'm reproducing the examples of Tim Baldridge's O'Reilly course: https://resources.oreilly.com/examples/0636920041474/blob/master/Communicating%20Sequential%20Processes%20with%20core.async%20-%20Working%20Files/Chapter%205/Introduction%20to%20backpressure/Lesson_Introduction_to_Backpressure.clj

(def c (chan 24))

(go 
  (loop [i 0] 
     (println "Putting: " i) 
     (>! c i) 
     (recur (inc i))))

(<!! c) 
This code demonstrates back pressure. Whenever I take a value from the channel with
(<!! c)
a new value is put onto the channel by the loop. I closed the channel with
(close! c)
to see what happens. Strangely, the loop no longer blocked and started printing thousands of "Putting: ..." lines. How can this be explained? I would have expected an error.

dpsutton 2020-06-30T14:20:28.016200Z

> puts a val into port. nil values are not allowed. Must be called > inside a (go ...) block. Will park if no buffer space is available. > Returns true unless port is already closed. if the put doesn't succeed, it returns false. You are attempting to put onto a closed channel which immediately returns false and then you loop again

dpsutton 2020-06-30T14:21:13.016500Z

(docstring from >!)

dpsutton 2020-06-30T14:23:31.017100Z

using the >!! version but demonstrates a similarity:

(let [closed-chan (doto (a/chan) (a/close!))]
  (a/>!! closed-chan 3))
=> false

dpsutton 2020-06-30T14:24:34.017600Z

i believe your expectation was that this would block forever as it was unable to put onto the closed channel

niveauverleih 2020-06-30T14:53:45.018Z

I see. Thanks!