This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-06-25
Channels
- # announcements (2)
- # asami (16)
- # babashka (55)
- # beginners (27)
- # calva (14)
- # cider (5)
- # clj-kondo (16)
- # cljs-dev (22)
- # clojure (72)
- # clojure-europe (89)
- # clojure-nl (10)
- # clojure-uk (7)
- # clojured (1)
- # clojurescript (14)
- # community-development (4)
- # core-async (15)
- # emacs (10)
- # events (2)
- # fulcro (3)
- # graalvm (1)
- # graalvm-mobile (71)
- # helix (7)
- # honeysql (2)
- # introduce-yourself (1)
- # jobs-discuss (17)
- # juxt (3)
- # lsp (62)
- # malli (13)
- # meander (7)
- # off-topic (14)
- # pathom (54)
- # polylith (6)
- # re-frame (11)
- # releases (1)
- # sci (22)
- # sql (9)
- # tools-deps (84)
- # vim (37)
- # xtdb (18)
I'm looking to express the following: • A sequence of channels are expected to have a single keyword value to indicate if the prodcuer attached to the channel has started (:started) or encountered an error (:error) • All channels should be read. • A timeout should be applied to the read of all channels as a sequence to prevent deadlocks from an unresponsive producer. I've come up with the following, and am looking for a quick yea/nay on the idiomatic style.
(def c1 (async/chan 1))
(def c2 (async/chan 1))
(def c3 (async/chan 1))
(doseq [c [c1 c2 c3]]
(async/put! c :started))
(defn started? [& responses]
(every? #(= :started %) responses))
(def c4 (async/map started? [c1 c2 c3]))
(let [t (async/timeout 5000)
[v p] (async/alts!! [c4 t])]
(cond
(= p t) "Timed out!"
(true? v) "All channels started!"
(false? v) "One or more channels failed to start!"
:default "Unknown case"))
Odd that map would act that way, as map returns a channel which (i would think) could be composed as such. If i execute my example without the doseq put! operation on c1 c2 c3, it does in fact time out at the repl.
the same timeout behavior if i put! on c1 c2, but not c3
a put! on all 3 channels results in "all channels started!"
The thing to understand is map is starting a go block which is basically copying from the input to the output. And your timeout has no effect on that process
In particular for map, leaving the map process sitting around doing that copying likely is not a big deal
If I recall the output channel is unbuffered and the map process will just wedge writing to it until it gets gc'ed
But in general leaving that kind of process sitting around can cause things to behave unexpectedly (if the channel is buffered, or channels aren't being used as one shot value conveyors)
At the very least I think you'd be better off using something like merge over map, because mapping is ordered and you don't car about order
acknowledged. thanks