What are the effects of using close!
on a subscription channel without first using unsub
?
Will this have the effect of an implicit unsub
+ a close!
or will there be any unwanted sideeffects doing so?

- 6,882
- 13
- 44
- 87
2 Answers
I wasn't able to determine the answer from the docs, so I made a small async experiment to determine whether close!
without unsub
is safe.
(ns pubsub.experiment
(:require [clojure.core.async :as >]))
(def publisher (>/chan))
(def p (>/pub publisher (constantly nil)))
(def answers (>/chan))
(defn consume
[label count]
(let [s (>/sub p nil (>/chan))]
(>/go-loop [i 0]
(if (> i count)
(>/close! s)
(do
(>/>! answers [label (>/<! s)])
(recur (inc i)))))))
(defn -main
[& args]
(println "running pubsub experiment")
(consume :a 1)
(consume :b 2)
(consume :c 3)
(consume :d 4)
(consume :e 5)
(>/go-loop []
(println "result: " (>/<! answers))
(recur))
(>/<!! (>/onto-chan publisher (range 10)))
(System/exit 0))
and then running it (bench.jar is an uberjar containing clojure plus core.async and a couple of other libs).
$ java -cp ~/bin/bench.jar:. clojure.main -m pubsub.experiment
running pubsub experiment
result: [:a 0]
result: [:b 0]
result: [:c 0]
result: [:d 0]
result: [:e 0]
result: [:a 1]
result: [:b 1]
result: [:c 1]
result: [:d 1]
result: [:e 1]
result: [:b 2]
result: [:c 2]
result: [:d 2]
result: [:e 2]
result: [:c 3]
result: [:d 3]
result: [:e 3]
result: [:d 4]
result: [:e 4]
result: [:e 5]
$
As we can see, the close!
calls don't interfere with any of the other subscribed channels, and each channel sees all the results we expect before closing.

- 20,076
- 2
- 41
- 49
pub
and sub
are implemented in terms of mult
:
each topic of a publication channel corresponds to a mult created when the first subscription for that topic is registered,
each
sub
call results in an under-the-hood call totap
on the mult corresponding to the relevant topic.
Mults are internally set up to remove taps that end up putting to a closed channel (this is documented in the docstring of mult
). In the context of subscriptions, that means that if a subscription channel is closed, its tap will be removed from its mult the first time a message for that topic is published to the publication channel, or in other words, close!
does cause an implicit unsub
.
Note that neither unsub
nor close!
cause the topic itself (and the corresponding mult) to be removed from the publication's register. If you want that to happen, you can use unsub-all
.

- 83,634
- 13
- 201
- 212