Anybody work with go goroutines? I have a few ques...
# coroutines
a
Anybody work with go goroutines? I have a few questions about concepts and how similar they are to kotlin coroutines
l
I didn't use Go, neither goroutines, but I know in Go, all functions can suspend, while in Kotlin, only
suspend fun
are allowed to do so.
a
Kotlin coroutines are more or less syntactic sugar to write non blocking code more nicely -- And if you write blocking code inside coroutine its still blocking and bad
But apparently - go runtime can detect blocking calls and offload them into its own worker pool?
Its making me confused about how to deal with blocking code in kotlin coroutine now lol -- we make our own fixedThreadPool.asCoroutineDispatcher and run it on that
v
But apparently - go runtime can detect blocking calls and offload them into its own worker pool?
Something like this, it has all its syscalls instrumented at runtime level. When blocking syscall is detected, current thread offloads all its work to another thread and signals that it is “blocking” (so runtime can create or unpark one more thread)
we make our own fixedThreadPool.asCoroutineDispatcher and run it on that
More or less, depending on your blocking frequency and CPU-load. Latest release has experimental dispatcher, which has smarter blocking code execution (though you still should directly mark code as blocking)
d
go routines are just the CommonPool and the Channel system; To compare with Kotlin
🚫 1
go function()
is
launch { function() }
a
@Vsevolod Tolstopyatov [JB] when we talk about coroutines we talk about a new/better/simpler way of writing async code - avoiding call backs and rx. Would you agree with the statement that coroutines are syntactic sugar to avoid callbacks? Because in go - i never hear this. All i m seeing everywhere , even at work, is - goroutines are cheap just launch as many as you want and do whatever you want in them. No talk about thread pools or blocking or anything
v
@asad.awadia I would not. Coroutines are standalone feature, for example take a look at stdlib
buildSequence
. Is it a wrapper over callback? Is
suspend fun foo(): Unit
a wrapper over callback? Coroutines allow to translate callback-based code to “sequential”-ish, but it’s not a syntactic sugar to avoid callbacks, it’s something bigger (syntactic sugar over state machines 🙂) Go is a different beast, goroutines have runtime support, but they are tightly coupled with it, so you don’t have access to state machine,
continuation
and therefore to handy features as
buildSequence
, generators or Erlang-like state machines
Goroutines are rather Kotlin `async`/`launch` like coroutines with powerful runtime support, while coroutines are broader feature, but without runtime support (because we can’t add feature to the JVM itself). In terms of runtime cost, both goroutine and
launch
have roughly the same footprint
a
Yes that’s exactly what I mean by syntactic sugar as well - they allow translation from callback based code to sequential ish code :)
Koroutines/goroutines aren’t magic though right? That just because you can launch thousands of these you can just do more stuff if you are spinning one off for blocking work - at the end of the day you are still blocking - just blocking another thread
The code inside still needs to be non blocking?
For n threads - launching n+1 coroutines that all have blocking work - the last 1 coroutine has to wait yes? Which is no different than just running it on threads and blocking it there
v
The fact that feature simplifies
X
doesn’t automatically means that the feature is a syntactic sugar over
X
🙂
at the end of the day you are still blocking - just blocking another thread
Yes.
The code inside still needs to be non blocking?
For Go it doesn’t matter. Go detects blocking calls from runtime and offloads them to “blocking” threadpool (kind of, Go scheduler is a bit more complicated). For
kotlinx.coroutines
-- yes, or you should offload blocking calls to another threadpool.
For n threads - launching n+1 coroutines that all have blocking work - the last 1 coroutine has to wait yes?
Yes.
Note though, that many APIs (maybe except for file I/O) have non-blocking API (e.g. nio) and with a help of “syntactic sugar” you now can write the same sequential-ish code, which uses non-blocking API underneath, making the code scalable and programming model simple. E.g. you can’t have 100000 threads bound to long-polling connections with reasonable performance, but you can have 100000 coroutines, one per connection. Without coroutines to properly handle 100000 connections you should use some callbacks/event-based APIs like netty or jetty’s asynchronous servlets which are easy to get wrong
a
Do you have examples of production (more advanced) usages of coroutines?
I’d really like to solidify my understanding by reading code that actually demonstrate a bit more advanced usage
v
take a look at Ktor examples. Ktor has coroutine-based API down to the network stack