yep! i've already switched my nodejs project to using them and they're working perfectly 🎉
I watched Rich Hickey's talk "maybe not" and I love the idea of s/select
I wonder why there's go-loop
but not thread-loop
shorthand in core.async
I think it's because go has to do tricky body rewrites, and go-loop can reduce that complexity compared to using loop
go-loop just expands to (go (loop ...))
, I don't see how that could help rewrites https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L458-L461
because you shouldn't be looping in threads 🙂
a loop is usually going to wait on a timeout or a channel, both of which should be things you do in go loops,
and just do (async/<! (async/thread ...))
for io
That's interesting and makes sense. But if I'm going to do IO for every input message, is it efficient to wrap every IO op in a thread, rather than the whole loop?
It seems core.async is pooling and reusing the threads so I guess it might be OK
use (<! (thread (blocking-op)))
inside go-loop
the pool is small and easy to exhaust / congest
I think which is best is kind of a thorny question, but it is clearly the design core.async pushes you towards
oh - did you mean the core.async/thread
threads? yes those are pooled too, and I think the usage of thread to do one blocking op, letting you park on the result in the thread's channel, is the intended pattern
Yes that's what I meant. Thanks for the ideas 🙂 I am reconsidering loops in my components now.
> because you shouldn’t be looping in threads 🙂 I’ve recently done this and now I dubious if what I did was right.
(dotimes [_ n]
(async/thread
(loop []
(if-some [url (async/<!! ch)]
(let [...]
(do-work)
(recur id))
(log/info ::close)))))