Spring WebClient is blocking the thread

Viewed 2303

Spring WebClient is supposed to be non-blocking (reference doc). But when I was trying it out in a sample demo code, it was blocking the main thread.

When I run the below code I get the following output:

main: main
runBlocking: main
async: main
304 //length of output
wait over in 2346
after async

I was expecting that "after async" would print before "304" (output of API call) as the API should not block the main thread and main() function should carry on with code that is after the async block.

Main Code::

import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.springframework.http.client.reactive.ReactorClientHttpConnector
import org.springframework.web.reactive.function.client.WebClient
import reactor.netty.http.client.HttpClient
import kotlin.system.measureTimeMillis


fun main() {
    val httpClient = HttpClient.create()
    val client: WebClient = WebClient.builder()
        .baseUrl("https://postman-echo.com/get?foo1=bar1&foo2=bar2")
        .clientConnector(ReactorClientHttpConnector(httpClient))
        .build()
    println("main: " + Thread.currentThread().name)
    runBlocking {
        println("runBlocking: " + Thread.currentThread().name)
        async {
            println("async: " + Thread.currentThread().name)
            val time = measureTimeMillis {
                val out = client.get().retrieve().bodyToMono(String::class.java).block()
                println(out.length)
            }
            println("wait over in $time")
        }
        delay(1)
        println("after async")
    }
}
1 Answers

Consider using .awaitBody<T>() instead of .block() (which is blocking operation)

Something like:

val out = client.get().retrieve().awaitBody<String>()
Related