(Let me know if you think this belongs in some kin...
# coroutines
m
(Let me know if you think this belongs in some kind of "self-promotion" rather than here.) Hi! When I was studying coroutines and started to really get it, I started to write a guide the way my brain would've wanted it all explained (and for my team colleagues as we were all slowly migrating to Kotlin). After a few years sitting on the internal company network, I've now refined it and put it up on my website: expeditionstudio.eu/kotlin-coroutines.html Maybe there is someone out there learning coroutines with a brain that wants it explained the way my brain wanted it! 🙂 (Thinking about putting it up in a series of Dev.to-articles as well if I get around to it)
kodee loving 2
🚀 2
r
404
➕ 2
m
Darn Apache config 😄 Better now I hope?
👍 1
c
I'm only at the start, but it may be important to mention that
runBlocking
is not parallel by default, so "wrapping the entire application in `runBlocking`" doesn't improve performance
I did not take this literally enough the first time I read it, but it truly is just “a thing”. To put it differently, a
Job
is a tool you can use to describe and manage anything that fits this description.
Yeah. I like to describe
Job
as a remote control. You have a button to cancel it, a button to wait for it, etc, but the
Job
itself isn't the work.
m
Thanks for the feedback! 🙂
c
> Well, cancellation is done using exceptions (A decision I know has been debated, however I have no insight into what the alternatives were). That's not really true. Cancellation happens entirely within
Job
. When
.cancel()
is called, the
Job
is marked is marked cancelled and the Coroutines mechanisms know the coroutine is cancelled, without any exceptions. The problem is: what happens to existing code? It is possible to just stop scheduling the coroutine, and so it blips out of existence right where it was.
Copy code
coroutineScope {
    val a = launch {
        …
        delay(100)
        …
    }

    a.cancel()
}
Here, the coroutine would just disappear and never execute any more code. The problem is if the user wrote:
Copy code
coroutineScope {
    val a = launch {
        val file = File("…").open()
        try {
            delay(100)
        } finally {
            file.close()
        }
        …
    }

    a.cancel()
}
If the coroutine just disappeared, the
finally {}
block would never be executed,
.close()
would never run, and there would be a resource leak. Not good! So anytime a coroutine gets killed (whether it's cancellation, or an error in a child coroutine, or anything else), the Coroutines library already knows that but will still throw an exception in the coroutine just to be sure that
finally
blocks are executed
(and potentially other
try…catch
).
try…finally
complicates many parts of the Kotlin language. This is one example, there are a few others.
Still, what's important to understand is that even if you catch the
CancellationException
, the parent still knows that the child has been cancelled: the exception isn't used to pass the message around, it's only used to give it a chance to the coroutine to orderly shut itself down.
Nice read!
It's good to have an all-in-one explanation like this
m
Thank you!! I'll see if I can find the time to have a think around your suggestions and some possible re-phrasing, but have some other things to tend to the coming days... (New video with the band dropping tomorrow, apparently one has to "create content" for social media nowadays... 😉 )
o
Congratulations on crafting that piece! It’s quite long, but well researched and really comprehensive, so that I'd recommend this to everyone who wants to get a full understanding of coroutines. ❤️
m
Thanks Oliver! 🙂