core-async

dangercoder 2019-03-29T07:25:33.034200Z

The main difference between Golang and Clojures Core-Async is that in Golang you do not have to care about "Blocking"?

dangercoder 2019-03-29T07:26:01.034300Z

or would that be sorted using the async/thread-macro? i am trying to find some good reading material on this topic

2019-03-29T12:09:23.034500Z

Yes, golang has a scheduler that detects blocking sys calls and spins up a new physical thread: https://github.com/ardanlabs/gotraining/tree/master/topics/go/concurrency/goroutines

2019-03-29T12:11:41.034700Z

core.async doesn't have a scheduler so having blocking IO is a bad idea, you risk dead locking core.async's threadpool

bertofer 2019-03-29T14:25:44.035Z

@danboykis thanks for the gotraining link, it has some specifics for coroutine and channel designs and also other generic software design ideas, liked it 👍

👍 1
dangercoder 2019-03-29T14:48:39.035300Z

I really liked it as well, thank you @danboykis! 🙂

idiomancy 2019-03-29T23:10:19.036700Z

so, I have this really common problem in core.async and have yet to figure out what the "correct" answer is

idiomancy 2019-03-29T23:10:54.037500Z

basically, I need to go from channel of channels to channel of values

idiomancy 2019-03-29T23:12:03.039Z

so, I have a channel that contains a list of values, and I perform an async call on each of those values, and the async call returns a channel. Now I have a channel that has a list of channels

2019-03-29T23:12:22.039700Z

continue, but my guess is you need to switch a map somewhere for pipeline or pipeline async

2019-03-29T23:12:33.039900Z

yeah, use pipeline

idiomancy 2019-03-29T23:12:49.040100Z

oh really?

idiomancy 2019-03-29T23:13:44.041100Z

at what point? supposing I have a channel where each value is a list of ten urls

2019-03-29T23:13:46.041200Z

depending, maybe merge

idiomancy 2019-03-29T23:14:36.042400Z

ideally, ultimately, I want a channel where each value is the result of the get call

2019-03-29T23:15:11.043500Z

(pipeline-blocking 8 output-chan (map fetch) (onto-chan list-of-lists-of-urls))

idiomancy 2019-03-29T23:16:59.044500Z

hmm.. so

(pipeline-blocking 8 output-chan (map (partial map fetch) input-chan)
is my situation.

idiomancy 2019-03-29T23:17:23.044900Z

and then I still have a channel where each value is a list of channels

2019-03-29T23:18:25.045400Z

(comp cat (map fetch))

idiomancy 2019-03-29T23:19:03.046100Z

oh, so that cat is going to emit values one at a time? that wouldn't say, wait for all the fetches to produce a value?

idiomancy 2019-03-29T23:20:29.047100Z

if thats the case I guess I could just (pipeline-blocking 8 output-chan cat (onto-chan [(chan) (chan) (chan)]) right?

idiomancy 2019-03-29T23:21:00.047600Z

well, to be more specific..

idiomancy 2019-03-29T23:24:03.050100Z

(pipeline-blocking 8 output-chan cat 
    (to-chan [(go 1)  (go (<! (timeout 1000)) 2) (go (<! (timeout 4000)) 3)]))
so in this case, would output-chan require 0 seconds or 4 seconds to emit its first value?

idiomancy 2019-03-29T23:34:58.051Z

yeah, I still cant get this to work in any way

idiomancy 2019-03-29T23:35:47.051400Z

im really not sure how pipeline helps me here, actually

idiomancy 2019-03-29T23:50:09.052100Z

well, having no "correct" way of doing things, here's what I have been doing.

(defn chain! [in!]
  (let [out! (a/chan)]
    (a/go-loop
      [next! (a/<! in!)]
               (if next!
                 (do
                   (<! (go (loop [subval (a/<! next!)]
                             (when subval (a/>! out! subval)
                                          (recur (a/<! next!))))))
                   (recur (a/<! in!)))
                 (a/close! out!)))
    out!))