5
votes

One of the key concepts of coroutines in Kotlin is that a suspend function must be called from a coroutine or another suspend function.

However, a suspend function can call any kind of function, suspend or normal.
What is the consequence of that? (This is not a real scenario i have, just want to know for theoretical reasons)

I imagine that in that scenario the only point of creating a coroutine would be to change the context (thread) before calling it, so it doesn´t block the main thread. However, would all the other advantages of coroutines be lost? (cooperative cancellation, structured concurrency...)

3
nothing, literally nothing. except when you have to call withContext because of the non suspending method has relations to the UI - coroutineDispatcher

3 Answers

3
votes

If a suspending function calls another suspending function, then the coroutine is suspended, until the result is returned.

Calling a regular function from a suspending function will block the thread. Which thread? Well, that depends on the Dispatcher you're using. IO is able to spawn hundred of threads. But the Default dispatcher has same amount of threads as your CPUs count. Meaning that while this won't block other coroutines, it will reduce the amount of available resources.

Meaning: don't invoke non-suspending function that may block for a long period of time on this dispatcher, same as you don't block your UI thread.

And yes, suspending function may produce the same results, if you're do something like a busy loop without yield() or any other suspend invocation in it.

1
votes

Suspend functions can be suspended in between and resumed later. Calling a normal function from a suspend function you lose the ability to pause the execution.

when a suspend function is compiled, kotlin compiler adds a continuation object as a parameter in the arguments. This continuation object is required for suspending a the coroutine. When a suspend function calls another suspend function it passes the continuation object same is true with co-routines.

if a non-suspend function is called from suspend function you just wont be able to use co-routines from that function... that's it

1
votes

However, would all the other advantages of coroutines be lost? (cooperative cancellation, structured concurrency...)

Even a non-suspendable function can participate in cooperative cancellation by explicitly checking the CoroutineContext.isActive flag. This is more of a theoretical fact, though.

If a function performs a blocking IO operation, it will not respond to cancellation requests. The operation will have to complete on its own.

As for structured concurrency, almost the opposite of your concern is true: it is a Kotlin best practice to launch child coroutines from a non-suspendable function that is instead an extension on CoroutineScope and calls the coroutine builders with it as the receiver.