Skip to content

Coroutines guide should highlight the dangers of runBlocking #4412

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
dkhalanskyjb opened this issue Apr 15, 2025 · 1 comment
Open

Coroutines guide should highlight the dangers of runBlocking #4412

dkhalanskyjb opened this issue Apr 15, 2025 · 1 comment
Labels
guide Issues with the coroutines guide on the website

Comments

@dkhalanskyjb
Copy link
Collaborator

Reported by @joffrey-bion in the Kotlinlang Slack.

Currently, the coroutines guide uses runBlocking freely to explain the concept of coroutines. However, in practice, runBlocking does not have such a prominent role and is often error-prone: #4242

At the top level, there is an alternative to runBlocking:

suspend fun main() {
    coroutineScope {
        // code goes here
    }
}

It's not without its issues, though: it silently introduces multithreading (because no dispatcher is specified, Dispatchers.Default is used).

I don't see a way around using the single-threaded runBlocking for some of the examples, but the issues with runBlocking should be highlighted.

@dkhalanskyjb dkhalanskyjb added the guide Issues with the coroutines guide on the website label Apr 15, 2025
@kevincianfarini
Copy link
Contributor

I mentioned this in #4242, but it's worth noting that suspending main functions aren't supported on native targets yet, only on JVM iirc. runBlocking of course isn't offered on js, but that seems like a much smaller use case than the myriad of native targets.

Would something like this suffice in the guide if runBlocking gets marked as delicate?

// Opt-in to delicate behavior from runBlocking. 
// It should only ever be used when bridging the synchronous world 
// which is known to not be called from any coroutine. 
@OptIn(DelicateCoroutinesApi::class)  
fun main() = runBlocking {
  /* TODO */
}

It might also be good to include examples of bad behavior. Eg:

suspend fun foo() {
  bar()
  baz()
}

suspend fun bar() { /* TODO */ }

fun baz() = runBlocking { // BAD: This is called from a suspending function but invokes runBlocking. 

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
guide Issues with the coroutines guide on the website
Projects
None yet
Development

No branches or pull requests

2 participants