Fork me on GitHub
#core-async
<
2018-02-07
>
xiongtx07:02:29

How do go blocks "unpark" themselves? IIUC , when they part they release the thread to work on another go block. What tells the thread that the first go block is ready to be worked on again?

tbaldridge14:02:50

@xiongtx go blocks don't park as much as they turn themselves into a callback (could be though of as a continuation). So when they "park" they simply attach a callback to something. Most of the time it's handed to a call ot (async/put! c v callback)

xiongtx17:02:05

@tbaldridge Found this extremely helpful walkthrough of core.async/go: http://hueypetersen.com/posts/2013/08/02/the-state-machines-of-core-async/ IIUC the channel is responsible for restarting the state machine.

noisesmith18:02:28

there’s an async-dispatch process that matches up channel reads and writes to resumption of pending reads and writes in eligible go blocks (expressed as callbacks)

noisesmith18:02:54

the channel itself is a queue used by that disptach process as I understand it

noisesmith18:02:06

(though now that I think of it more there must be a mechanism that marks the channel for potentially activating go blocks when the channel is read or written outside of a go state machine)

hiredman18:02:37

there isn't a dispatch process

noisesmith18:02:53

oh, I thought I’d seen this in my stack traces

hiredman18:02:36

the acting of publishing or consuming from a channel can cause things to be run on a threadpool

noisesmith18:02:59

oh, so it is the channel driving it, like @xiongtx was saying? cool

hiredman18:02:24

so there is no global process watching it all

noisesmith18:02:28

right, now I see that thread-pool-executor names its threads async-dispatcher-%d for N threads

noisesmith18:02:43

I misinterpreted those in my stack traces

hiredman18:02:02

which is why go blocks aren't gc roots

xiongtx18:02:31

Can you elaborate on this a bit more? I’ve some basic understanding of how Java GC works, but what makes something a root?

noisesmith18:02:05

ahh, they can get gc’d if the relevant channels are gc’d? - it’s starting to make more sense now I think

xiongtx18:02:25

@noisesmith The point is that it’s cooperative multithreading; there’s no scheduler involved. This also means that the runtime cannot help you when you perform IO in a go block. Eli Bendersky has a great piece on this: https://eli.thegreenplace.net/2017/clojure-concurrency-and-blocking-with-coreasync/

noisesmith18:02:04

@xiongtx I wasn’t imagining a preemptive scheduler, I was imagining a book-keeper that figured out which parked things were able to run

noisesmith18:02:23

but of course the channels are fully qualified to do that, so there’s no need for such a book-keeper

noisesmith18:02:06

regarding gc roots, a gc root is data that the gc can’t claim implicitly - for example if you have cyclical object references that contains no path to a root, all objects in that cycle qualify for gc

noisesmith18:02:38

but if they are accessible from a root they remain alive

xiongtx18:02:24

I understand that part…I guess the point is that since there’s no “book-keeper” for the go blocks they’re not reachable from any GC root?

xiongtx18:02:00

B/c nothing holds a (strong) reference to them unless it’s 1) the thread that’s running the block or 2) the channel that uses the SM as a callback

noisesmith19:02:11

I think that not only are those the only strong references, but those are the only references period unless you do some shenanigans