This is an automated archive made by the Lemmit Bot.
The original was posted on /r/programminglanguages by /u/smthamazing on 2024-11-09 15:55:26+00:00.
I’m not well-versed in the topic and not very familiar with Kotlin, so apologies for a possibly silly question.
In most languages I work with (C#, JavaScript, Rust) you have to explicitly pass around a cancellation signal to async functions if you want to be able to cancel them. This sometimes leads to bugs, because regular developers and library authors either forget to pass such a signal to some deeply nested asynchronous call, or consciously don’t do this to avoid introducing an extra parameter everywhere.
In Kotlin, however, functions marked with suspend
can always be cancelled, which will also cancel every nested suspend
function as well. There are other things that feel a bit magical on the first glance: for example, there is a function called async that turns a coroutine call into a Deferred
, which is seemingly implemented on the library level and not by the compiler. There is also the launch function that wraps a call into a cancellable job. All this makes Kotlin’s concurrency “structured” by default: it’s difficult to forget awaiting a function call, because all suspend
functions are awaited implicitly.
My question is: how does it work? How do “inner” coroutines know that they should also cancel when their caller is cancelled? What kind of abstraction is used to implement stuff like async
and launch
- is there some kind of internal “async executor” API that allows to subscribe to suspend function results, or…?
I’m asking this because I’m figuring out ways of implementing asynchronicity in my own compiler, and I was impressed by how Kotlin handles suspend
calls. Also note that I’m mostly interested in single-threaded coroutines (that await e.g. IO operations), although thoughts on multithreaded implementations are welcome as well.
P.S. I know that Kotlin is open source, but it’s a huge code base that I’m not familiar with; besides, I’m generally interested in state-of-the-art ways of coroutine implementations.