I want to use Kotlin coroutines in my reactive sql client transactions.
For simplicity, I was going to use the provided helper function io.vertx.mutiny.sqlclient.Pool#withTransaction
mentioned in the docs here. Since the passed function is not a coroutine suspend function, I'm getting an error like Suspension functions can be called only within coroutine body
when Im trying to compile a code like the following
val client : PgPool
...
suspend fun someServiceFunction () {
client.withTransaction { connection ->
repository.save(connection, entity).awaitSuspending() //This is not working
...
}
}
The function header for the withTransaction looks like this
@CheckReturnValue
public <T> Uni<T> withTransaction(Function<SqlConnection, Uni<T>> function)
I'm asking myself if there is still a way to use this with kotlin coroutines, since I'm pretty new to them.
Thank you for any help !
CodePudding user response:
I'm not familiar with Mutiny nor Quarkus, but it seems there is a way to convert from Deferred<T>
to Uni<T>
in mutiny-kotlin
, which you seem to be using.
You could therefore create your own suspending version of withTransaction
like this:
import io.vertx.mutiny.sqlclient.SqlConnection
import io.vertx.mutiny.sqlclient.Pool
@OptIn(ExperimentalCoroutinesApi::class)
suspend fun <T> Pool.withTransaction(block: suspend (SqlConnection) -> T): T = coroutineScope {
client.withTransaction { connection ->
async { block(connection) }.asUni()
}.awaitSuspending()
}
And then use it:
suspend fun someServiceFunction() {
client.withTransaction { connection ->
repository.save(connection, entity).awaitSuspending()
// potentially other suspending stuff here, without the need to combine()
}
}
But that begs the question, why use the Mutiny variant of Vertx things, if in the end you want to use Kotlin coroutines? I think by default Vertx works with Java futures which are also integrated with coroutines.