1

I've been delving into Kotlin Coroutines and discovered that suspending functions can simplify the creation of asynchronous and non-blocking code when using Kotlin and Coroutines. In an Android application, making Network Requests as suspending functions is crucial to prevent blocking the Main Thread.

However, in a Spring Boot Application, where the concept of a Main thread isn't as prominent, there are situations where we need to wait for the Network call to return before proceeding with the next steps, which might seem somewhat 'blocking'. I even attempted to apply the suspend keyword to my client calls and launch them within Coroutines. Interestingly, Kotlin sometimes suggests that the 'suspend' keyword is redundant.

This raises the question of whether Network Requests or other I/O-bound operations can truly be considered or implemented as suspend methods in a Spring Boot context. If there is a way to implement them as suspending functions, what advantages would this bring to REST calls?

// suspend here is redundant...in fact, if this call takes x seconds, my API request thread will be blocked for x seconds
suspend fun makeHttpRequest(): String {
    val client = HttpClient()
    val response = client.get<String>("https://example.com/api/endpoint")
    return response
}

fun main() {
    val numberOfThreads = 4 // Adjust as needed
    val threadPool = newFixedThreadPoolContext(numberOfThreads, "CustomThreadPool")

    runBlocking {
        repeat(numberOfThreads) {
            GlobalScope.launch(Dispatchers.Default + threadPool) {
                val result = makeHttpRequest()
                // Process the result here
            }
        }
    }
}
2
  • 1
    suspend won't make blocking calls suspendable by magic. The library you use has to be compatible, and since suspend is a Kotlin-only feature, Java libraries will not be. So either you have to implement your own wrapper, or find a library that makes your network requests coroutine-compatible. Commented Oct 14, 2023 at 8:15
  • A suspend function that doesn’t call any other suspend functions does not benefit from the suspend keyword and that’s why it tells you it’s redundant. If you want to convert a blocking call to a suspend one, you can use withContext(Dispatchers.IO) and if you want to convert an asynchronous call to a synchronous suspending one, use suspendCancellableCoroutine. Commented Oct 14, 2023 at 13:25

1 Answer 1

2

Async/non-blocking network stack works with coroutines if and only if you use Spring Webflux.

Spring provides non-blocking compatibility with coroutines through Reactor (reactive streams) and Netty.

You can get more information in the following blog post section: Webflux with coroutines API.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, Could my network request become asynchronous and non-blocking when using Java CompletableFuture and Kotlin Coroutines together?
@Drex: I am not sure about CompletableFuture/suspend functions compatibility. I also depends on how Spring handles CompletableFuture return values. And, also, since the latest JDK release, there's also virtual threads to account for, that could help making code non-blocking.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.