This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-10-15
Channels
- # announcements (1)
- # babashka (81)
- # beginners (48)
- # calva (49)
- # clj-kondo (52)
- # cljdoc (7)
- # cljs-dev (39)
- # clojure (33)
- # clojure-australia (18)
- # clojure-europe (48)
- # clojure-italy (2)
- # clojure-morsels (2)
- # clojure-nl (3)
- # clojure-uk (6)
- # clojurescript (5)
- # community-development (2)
- # conjure (6)
- # cursive (3)
- # data-science (29)
- # datalog (4)
- # datomic (14)
- # events (1)
- # fulcro (1)
- # graphql (18)
- # gratitude (2)
- # helix (11)
- # introduce-yourself (2)
- # java (15)
- # keyboards (2)
- # lsp (6)
- # luminus (4)
- # membrane (32)
- # minecraft (1)
- # missionary (7)
- # nextjournal (2)
- # off-topic (28)
- # portal (28)
- # releases (1)
- # ring (1)
- # shadow-cljs (3)
- # sql (6)
- # xtdb (23)
@leonoel I added an example of converting async channel to flow to the wiki, but now realized that it only works for clojure (not clojurescript). I have another version, but just wondered if you could have a look and let me know if it looks ok:
(defn- take! [chan]
(let [cancelled? (atom false)]
(fn [succ rejec]
(async/take!
chan
(fn [r]
(cond
(instance? #?(:clj Exception :cljs js/Error) r) (rejec r)
(or (nil? r) @cancelled?) nil
:else (succ r))))
(fn []
(reset! cancelled? true)
(rejec (ex-info "Cancelled" {:cancelled? true}))))))
(defn channel-flow [ch-recv]
(forever (take! ch-recv)))
I would start with that :
(defn >!
"Puts given value on given channel, returns a task completing with true when put is accepted, of false if port was closed."
[c x] (doto (m/dfv) (->> (a/put! c x))))
(defn <!
"Takes from given channel, returns a task completing with value when take is accepted, or nil if port was closed."
[c] (doto (m/dfv) (->> (a/take! c))))
Then use sp
to add error checksThat's beautiful, thanks!
Specifically, I'm not sure about the reject call inside the cancel handler - is that needed?
it is required that either success or failure callback is called exactly once, and this implementation doesn't enforce that
implementing tasks and flows by hand is not trivial, you should always favor using existing operators if possible (if not possible, I'd like to know more)
Thanks for the help! Using dfv as callback is something I didn't think about - seems very useful.