Hello community,
I’m currently working on a Spring Boot web application with a traditional three-layer architecture: controller, service, and
ApiClient
for blocking calls. Due to certain limitations, adopting a fully reactive approach isn’t feasible at the moment. However, we are keen on finding a middle ground to improve performance through parallel calls.
To achieve this, we are exploring Kotlin Coroutines(We have also explored CompletableFuture and @Asyc but not happy with it ). As a relative newcomer to coroutines, I’ve implemented a solution that seems to work, but I’m uncertain if it’s the optimal approach. Below is a simplified snippet of the current implementation:
@Service
class Service(
private val clientA: ClientA,
private val clientB: ClientB,
private val clientC: ClientC
) {
fun someFunction(): OrderForm {
runBlocking(RequestCoroutineContext()) {
val result1 = async(Dispatchers.IO) { callA() }
val result2 = async(Dispatchers.IO) { callB() }
val result3 = async(Dispatchers.IO) { callC(result1.await()) }
OrderForm(result1.await(), result2.await(), result3.await())
}
}
private suspend fun callA() = clientA.get()
private suspend fun callB() = clientB.get()
private suspend fun callC(value: SomeType) = clientC.get(value)
}
Initially, the
ApiClient
methods were not marked as
suspend
, but I’m now considering moving towards making these calls suspendable to bring them closer to the client:
class ClientA {
suspend fun getA() {
withContext(Dispatchers.IO) {
// blocking API call
}
}
}
class ClientB {
suspend fun getB() {
withContext(Dispatchers.IO) {
// blocking API call
}
}
}
class ClientC {
suspend fun getC(value: SomeType) {
withContext(Dispatchers.IO) {
// blocking API call
}
}
}
However, attempting to call these suspendable functions in
someFunction()
resulted in an exception
Handler dispatch failed: java.lang.NoClassDefFoundError: kotlinx/coroutines/reactor/MonoKt","stack_trace":"jakarta.servlet.ServletException: Handler dispatch failed: java.lang.NoClassDefFoundError: kotlinx/coroutines/reactor/MonoKt
related to
NoClassDefFoundError: kotlinx/coroutines/reactor/MonoKt
. I suspect this may be due to the fact that the actual API calls are not reactive and suspendable.
I’m seeking recommendations on the best way to handle coroutines in a single thread per request model with Spring Boot. I want to avoid marking private functions as suspended and continually wrapping code in scopes.
Any insights or guidance would be greatly appreciated.