do we consider pipe as a simple version of merge or mix? i mean it looks very similar to both.
I consider it just to be what it is - a means of connecting two channels
https://gyazo.com/029c68de8ce3a51a719883d5e87ee780.png Say we don't need the timeout, can it be written better?
(comment
;; 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
@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
i know we puy long operations on async/thread
only parking (channel) operations
but whats about clojurescript then?
so no blocking calls at all?
correct
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
yeah thats explains it
the channel ops like >!
and <!
appear to block but don't actually block and are sometimes said to "park" instead
so to sum up; do whatever but don't take thread-pool threads for your long span\blocking calls
i'm just trying to comprehend what implications we have running csp on a threadpool, rather than green-threads\fibers
it is both
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
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)
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
yeah it makes it clear now, thanks
aside from that above code is fine right?
yeah
alts! might be nicer then alt! there
same with timeout