Noob question again, I wish to understand what hap...
# coroutines
g
Noob question again, I wish to understand what happens underneath with coroutines. If the thread doesn't block, who does the actual work and calls the resume on the suspension point, for example
delay()
👍 1
o
delay
is actually one of the more complex bits, the specifics depend on the dispatcher you're using
if you're on JavaFx's Main dispatcher, it will re-use
Timer
to schedule and execute delays if you're on the Default dispatcher, it has its own scheduling logic that is very complex and can be viewed in
kotlinx.coroutines.EventLoop
and other classes
g
Ok, so it's more like event-driven, schedule an event after some T secs and when it's fired, resume the suspension, correct?
o
I guess, for a loose definition of an "event". It just stores the Continuation and resumes it when the time is up, there's no event that's explicitly fired really (i.e. you won't find a ResumeEvent or DelayEvent)
I think internally the scheduling code uses the word "task", specifically "delayed task", which is more appropriate
g
Ok, but something has to keep track of the time and invoke something, so that continuation stored on heap is referred to resume from the point where it left before... I think that more of low-level... Taking a different example say a network call, does some low level stuff notify that hey I got all the data so you please resume?
o
depends on how it's implemented 🙂 if it's just a wrapper over InputStream, it'll actually just switch over to Dispatchers.IO and block if it's using async IO, then usually that involves a selector thread that resumes coroutines that have data. you'd have to look at how ktor implements its sockets
g
Interesting, so with
<http://Dispatchers.IO|Dispatchers.IO>
how does "Thread doesn't block work? When I launch coroutines on
<http://Dispatchers.IO|Dispatchers.IO>
it spawns a large pool of threads, which eventually block and wait for the data, right?
o
it's expected that code on
<http://Dispatchers.IO|Dispatchers.IO>
does block, it's the exception to allow compatibility with blocking code
g
Ooh... so if I have only one network call to make,
<http://Dispatchers.IO|Dispatchers.IO>
would allocate me one thread, which blocks on
InputStream
, right?
o
yes
g
good to know... so it's as good as spawning a thread ourselves
so IO is handy when I have multiple concurrent network calls
o
yes, though note it can still run out of threads (it only has max(64, # processors) by default)
g
that is right... where can I really leverage the "Light weight threads" philosophy, only for non-blocking operations?
like some concurrent computations?
o
concurrent computations, more straightforward code when writing UI applications (you can easily swap between the UI thread and processing threads without needing any sort of concurrency system)
you can handle thousands of web requests without a large thread pool, by off-loading the IO to the IO dispatcher and having any waiting that needs to be done
suspend
rather than block
g
But with IO dispatcher, we are using a limited thread pool of 64 bg threads, how is different from having a server with 64 threads that are all blocked?
Plus I assume IO threads and Request-Executor threads, all come from same shared pool of threads, what are we saving here?
o
that's true, you may need to look into using something like Ktor or custom code to use async IO
and the IO threads and Request-Executor threads are not the same, while
Dispatchers.Default
and
<http://Dispatchers.IO|Dispatchers.IO>
may share threads, if needed they will use new ones to their pool limit
g
Ok, so for a particular server, there is a separate pool that handles requests and separate for (IO + Default+ (... more on the run))?
o
personally I would just handle requests on
Default
, that's part of the "lightweight" bit -- you don't really need a bunch of thread pools, you can mostly use the 2 given to you
you might use a custom IO dispatcher to increase the thread count, or you can just set the IO dispatcher's thread count via system property
unfortunately I can't really find a benchmark or anything about coroutine-based servers vs. normal Java servers
g
hmm ya, I tried searching for some benchmarks as well but in vain... Thanks alot @octylFractal for all the knowledge sharing 🙂