mult

added

ns
clojure.core.async

type
function

(mult ch)

Creates and returns a mult(iple) of the supplied channel. Channels
containing copies of the channel can be created with 'tap', and
detached with 'untap'.

Each item is distributed to all taps in parallel and synchronously,
i.e. each tap must accept before the next item is distributed. Use
buffering/windowing to prevent slow taps from holding up the mult.

Items received when there are no taps get dropped.

If a tap puts to a closed channel, it will be removed from the mult.

                user=> (def sz 20)
#'user/sz

user=> (def c (chan sz))
#'user/c

user=> (def mult-c (mult c))
#'user/mult-c

user=> (def cx (chan sz))
#'user/cx

user=> (def cy (chan sz))
#'user/cy

user=> (def cz (chan sz))
#'user/cz

user=> (tap mult-c cx)
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@63942268>

user=> (tap mult-c cy)
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@1f025346>

user=> (tap mult-c cz)
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@29d4cd91>

user=> (put! c "sent to all")
true

user=> (<!! cx)
"sent to all"

user=> (<!! cy)
"sent to all"

user=> (<!! cz)
"sent to all"


            
                ;; Dont read from the source of mult, or you'll get read race contention

user> (def a (chan))
user> (def m (mult a))
user> (def b (chan))
user> (tap m b)
user> (go-loop [] (when-let [v (<! b)] (do (println "b got" v) (recur))))
;; next line is pain self inflicted 
user> (go-loop [] (when-let [v (<! a)] (do (println "a(source) got" v) (recur))))
user> (put! a "Hello ")
b got Hello 
user> (put! a " World")
a(source) got  World