Fork me on GitHub
Ivan Koz19:04:08

do we consider pipe as a simple version of merge or mix? i mean it looks very similar to both.

Alex Miller (Clojure team)20:04:47

I consider it just to be what it is - a means of connecting two channels

Ivan Koz22:04:34 Say we don't need the timeout, can it be written better?

  ;; search async, repllicated, take first
  (let [fake-search (fn [kind query]
                      (Thread/sleep (rand-int 100))
                      (format "%s search result for '%s'" kind query))
        fastest (fn [query ep1 ep2]
                  (go (alt!
                        (go (fake-search ep1 query)) ([v] v)
                        (go (fake-search ep2 query)) ([v] v))))
        search (fn [query]
                 (->> (async/merge [(fastest query "web 1" "web 2")
                                    (fastest query "image 1" "image 2")
                                    (fastest query "video 1" "video 2")])
                      (async/into [])))]
    (time (<!! (search "clojure")))))


you should never call Thread/sleep inside a go block


you absolutely should be using timeout channels and not faking it like that

Ivan Koz23:04:40

@hiredman i don't understand why, there is literally no difference between blocking operation and thread sleep inside a function


you should not have blocking operations inside go blocks

Ivan Koz23:04:27

i know we puy long operations on async/thread


only parking (channel) operations

Ivan Koz23:04:35

but whats about clojurescript then?

Ivan Koz23:04:54

so no blocking calls at all?


clojurescript inherits javascripts model, there is a single thread, any blocking/long running operations ever will block anything else


the threadpool used to run go blocks on the jvm is not single threaded, but that just means you can include blocking things like sleeps and it will work when you test at a small scale, and things will bog down and stop once you are at a large enough scale to saturate the threadpool


async/thread isn't for "long operations" it is for blocking operations

Ivan Koz23:04:50

yeah thats explains it


the channel ops like >! and <! appear to block but don't actually block and are sometimes said to "park" instead

Ivan Koz23:04:05

so to sum up; do whatever but don't take thread-pool threads for your long span\blocking calls

Ivan Koz23:04:31

i'm just trying to comprehend what implications we have running csp on a threadpool, rather than green-threads\fibers

Ivan Koz23:04:11

looking at that you wrote, i make conclusion that any IO task in a go block is a no no


go blocks are basically green threads, and those green threads are run on the real threads in the threadpool

Ivan Koz23:04:04

yeah but you can block green thread


it depends on the implementation


most of the time you cannot add green threads as a library, so the entire runtime system is built on around non-blocking io


so most green thread runtimes turn what appears to be blocking io calls in to non-blocking calls


go doesn't do that, but does some hand wavy stuff with it detects a go routine is blocked, giving the go routine its own thread


(hand waving by me because I don't remember and I think it has maybe changed since the last time I read anything about it)

Ivan Koz23:04:06

so inside go block, we should give any long-span\blocking operation it's own thread, except parking stuff


yes, and generally you want to park on the result of calls to async/thread

Ivan Koz23:04:16

yeah it makes it clear now, thanks

Ivan Koz23:04:10

aside from that above code is fine right?


alts! might be nicer then alt! there

Ivan Koz23:04:55

same with timeout