core-async

vemv 2020-01-02T03:57:14.142900Z

What's the reason for the seeming impossibility of having a rendezvous backed by a transducer? I'd like to use transducers for implementing some sort of message validator. It would be problematic if the validation ran for channels of buffer size 1, 2, 3, ... but not 0

alexmiller 2020-01-02T04:17:09.143600Z

transducers can be expanding and create new intermediate elements. those have to go somewhere so a buffer is required.

vemv 2020-01-02T04:19:25.145200Z

:thumbsup: I see! In a buffered chan, what happens when a transducer creates intermediate elements beyond the buffer's capacity? Does execution simply park, cleanly?

alexmiller 2020-01-02T04:21:39.145400Z

no, it overfills the buffer

vemv 2020-01-02T04:22:31.145800Z

would that cause an exception?

alexmiller 2020-01-02T04:24:10.146100Z

no, it expands to hold the extras

👍 1
2020-01-02T08:45:35.150800Z

I wonder about the behavior in this case. It will keep expanding even if the buffer is already larger than the original size. Pending puts will be executed upon a matching take, without checking whether the buffer is full according to original size. It just assumes that the new take operation releases space in the buffer. If every put is expanding, the buffer will expand indefinitely.

alexmiller 2020-01-02T14:05:10.151400Z

yes, so be careful about using expanding transducers (cat / mapcat are the only ones in core) in async channels

walterl 2020-01-02T20:27:26.152800Z

Hi everyone! n00b question: why does the following block forever, and not return [nil c] after c is close!d?

(let [c (chan)]
  (go
    (Thread/sleep 200)
    (close! c))
  (alts!! [c]))

2020-01-02T20:33:00.155100Z

My guess would be you've been playing around with core.async stuff for a while without restarting your repl, and as part of that playing around bat some point you did something that blocked up the threadpool go blocks run on

walterl 2020-01-02T20:34:10.155800Z

That is very likely. Checking...

walterl 2020-01-02T20:34:56.157Z

Indeed! Thanks @hiredman!

2020-01-02T20:35:05.157500Z

In general you also should not use thread sleep in go blocks, you should use a timeout channel

walterl 2020-01-02T20:35:21.157900Z

Sure. That was just to simplify an example

walterl 2020-01-02T20:36:05.158700Z

But this begs the question: is there some way that I can check for (and clear?) orphaned go routines, while I'm screwing around in the repl?

alexmiller 2020-01-02T20:38:38.160800Z

doing a thread dump will reveal that all the go threads are blocked (re detection), but no way to "clear" that

2020-01-02T20:38:58.161600Z

It is tricky, core.async doesn't really provide that, and the jvm just understands threads, so bridging that is tough

alexmiller 2020-01-02T20:39:51.162600Z

the key is no blocking ops in go blocks - obviously Thread/sleep does that (you can actually Thread/interrupt that), and i/o stuff. there is a new system property you can use to fail if a core.async blocking op is done in go blocks

💯 2
Avichal 2020-01-03T10:47:34.166600Z

Thanks for this. Where can I learn more on how to fail when there is blocking op is used in a go block?

walterl 2020-01-02T20:42:11.162800Z

"thread dump"? I'm not seeing anything relevant in my first few searches

alexmiller 2020-01-02T20:42:45.163Z

if you're on unix/mac, just do ctrl-\

alexmiller 2020-01-02T20:42:52.163200Z

or on windows ctrl-break

walterl 2020-01-02T20:43:26.163400Z

#TIL, thanks!

alexmiller 2020-01-02T20:44:38.164500Z

the threads are named async-dispatch-[1-8]

walterl 2020-01-02T20:46:17.165Z

Yeah, my actual implementation is CPU-bound. I was just using the Thread/sleep to test the hypothesis that alts!! won't "see" the closing of the channel, if done after alts!! started blocking on the channel.

2020-01-05T08:54:50.168200Z

Takes will see the channel closing, but pending puts will not and will block forever.

alexmiller 2020-01-02T20:46:31.165100Z

a thread able to be used is probably marked "WAITING (parking)"

alexmiller 2020-01-02T20:47:32.165300Z

if it's in a Thread/sleep, it will say "TIMED_WAITING (sleeping)". if it's blocked for some other reason, you may see other stuff

walterl 2020-01-02T20:47:44.165500Z

I was just about to ask 😉

alexmiller 2020-01-02T20:48:55.165800Z

yeah, I assumed

walterl 2020-01-02T20:50:50.166100Z

Thanks for the help, @hiredman @alexmiller!