core-async

jumar 2019-09-13T07:59:06.125900Z

Am I correct in that the usage of Thread/sleep is not recommended as in example from Brave clojure? https://www.braveclojure.com/core-async/#alts__

(defn upload
  [headshot c]
  (go (Thread/sleep (rand 100))
      (>! c headshot)))
Should one use thread instead (with >!! since >! cannot be used outside of go)?

jumar 2019-09-13T08:01:52.126Z

And btw. why does this keep printing different channel "strings" (I expected the same channels/pictures would lead to the same .toString representation):

(let [c1 (a/chan)
        c2 (a/chan)
        c3 (a/chan)]
    (upload "serious.jpg" c1)
    (upload "fun.jpg" c2)
    (upload "sassy.jpg" c3)
    (let [[headshot channel] (a/alts!! [c1 c2 c3])]
      (printf "Sending headshot notification for %s (%s)\n" headshot channel)))

Sending headshot notification for fun.jpg (clojure.core.async.impl.channels.ManyToManyChannel@77b6771a)
Sending headshot notification for fun.jpg (clojure.core.async.impl.channels.ManyToManyChannel@6c1ec55e)
Sending headshot notification for fun.jpg (clojure.core.async.impl.channels.ManyToManyChannel@7587449a)
Sending headshot notification for fun.jpg (clojure.core.async.impl.channels.ManyToManyChannel@5e13ba2d)
Sending headshot notification for serious.jpg (clojure.core.async.impl.channels.ManyToManyChannel@20ada533)
Sending headshot notification for serious.jpg (clojure.core.async.impl.channels.ManyToManyChannel@3e025718)

2019-09-13T08:14:24.126300Z

thread sleep will block worker thread that execute go-block code

jumar 2019-09-13T08:17:01.126600Z

Calling append-to-file inside the go block (https://www.braveclojure.com/core-async/#Queues) also doesn't look like the best approach

jumar 2019-09-13T11:59:29.127300Z

another question: how do people monitor core.async channels in practice? I couldn't find much about this stuff, only this http://tgk.github.io/2013/10/inspect-core-async-channels.html

markmarkmark 2019-09-13T13:43:14.127800Z

The more appropriate thing to do in that snippet would be (a/timeout (rand 100)) rather than the sleep

👍 1
jumar 2019-09-13T14:33:43.128Z

Yes, thanks, also found that option. In general, it seems that blocking calls are tricky. Either you have some sort of non-blocking IO lib or use threads with limited thread pool?

markmarkmark 2019-09-13T15:02:44.128200Z

yep. The only "blocking" calls that should be in go blocks are the parking >! <! operations.

markmarkmark 2019-09-13T15:03:15.128400Z

besides that you can quickly get around things by tossing the call into a a/thread call.

markmarkmark 2019-09-13T15:03:42.128600Z

and also remember that channels are very useful even outside of a core.async, go block context

jumar 2019-09-13T18:41:50.128800Z

@markmarkmark you mean using the blocking variants like &gt;!!, &lt;!!, alts!!, etc., perhaps with buffered channels? kind of like queues for decoupling components of your system?

markmarkmark 2019-09-13T18:45:41.129Z

right. you can just use those with plain threads.

markmarkmark 2019-09-13T18:45:56.129200Z

The channels don't even need to have buffers, but if you give them buffers then they are perfectly fine queues.

markmarkmark 2019-09-13T18:46:20.129400Z

There are plenty of reasons to have them without buffers still. See SynchronousQueue in Java

markmarkmark 2019-09-13T18:47:23.129600Z

for instance, you could have a plain thread that is blocking on io and then &gt;!! into a channel. one or more go blocks could be parked on that channel waiting for the input.

markmarkmark 2019-09-13T18:47:50.129800Z

a potential way to push the I/O to the outer edges of the program and ferry it into the core.async machinery if needed.

2019-09-13T18:52:43.132Z

we don't really monitor channels at work. we have some custom buffer types that report metrics, but those aren't really used, we mostly generate metrics for processes reading and writing to channels. how often they loop, how long each loop takes, how many messages they are sending out as they loop

👍 1
2019-09-13T18:54:19.132700Z

using custom buffer types for monitoring channels isn't that great, because buffers are only used if a channel cannot immediately hand off

2019-09-13T18:56:45.133600Z

a lot of the system where we use core.async the heaviest is very actor like, loops around reading from an input channel, and handling the message