Kotlin coroutines: Report usage of runBlocking

Description

When one start to use Kotlin Coroutines it may sometime be tempting to use runBlocking.

But in produciton it is generally a bad idea.

First of all it blocks a thread, which waste resources.

And it can also create a deadlock when called from a single-threaded context and one suspend until something is done that context. Here’s an example using JavaFx:

@FXML
fun handleAction() { // <-- Invoked by the JavaFx platform on the JavaFx platform thread
	runBlocking { // <-- Blocks the JavaFx platform thread
	
		// The following, schedule a job on the JavaFx platform thread and suspend until it has been executed.
		// but since the thread is currently blocked it will never be executed, and thus create a deadlock freezing the UI.
		withContext(Dispatchers.JavaFx) {	
			pritnln("hello from UI thread")
		} 
	}
}

Snippet of non-compliant code

fun usage() {
	runBlocking {
		delay(1000)
	}
}

Snippet of compliant code (fixing the above noncompliant code)

suspend fun usage() {
	delay(1000)
}

or

fun usage() {
	GlobalScope.launch { delay(1000) }
}

External references

The documentation of runBlocking itself states:

This function should not be used from coroutine. It is designed to bridge regular blocking code to libraries that are written in suspending style, to be used in main functions and in tests.

The kotlin team working on coroutines even wanted to make runBlocking fail fast when invoked from some UI threads: Fail-fast when trying to do `runBlocking` from Android UI thread · Issue #227 · Kotlin/kotlinx.coroutines · GitHub.

Type : Bug

May slow down the application or worse: cause deadlocks.

I would personally set the default severity to “Critical”

Tags

performance, multi-threading, pitfall

Scope: Production

runBlocking is legit and needed in tests.

Thank you very much, @jcornaz, for the effort put into specifying this rule. We will come up with a follow-up message once we evaluate all the rules you have suggested.

runBlocking has entirely valid use-cases e.g. when implementing callbacks from Java SDK’s in Kotlin and needing to make use of suspending code; small applications that must not quite before coroutines have completed etc. Just because it gets abused doesn’t mean it should be banned.