I'm trying to execute a db transaction with the vertx reactive sql client in a coroutine.
Somehow I can't figure out how I can convert the CompletableFuture
to the desired io.vertx.core.Future
type. Are there any helper methods or extensions to do this easily ?
val client : PgPool
...
suspend fun someServiceFunction () {
coroutineScope {
client.withTransaction { connection ->
val completableFuture = async {
repository.save(connection, requestDTO) //This is a suspend function
}.asCompletableFuture()
//Return type has to be a io.vertx.core.Future
//How can I transform the completableFuture to it ?
}
}
}
Thank you for your help !
CodePudding user response:
I adapted this from the code for asCompletableFuture()
to use as an alternative. Disclaimer: I don't use Vert.x and I didn't test this.
fun <T> Deferred<T>.asVertxFuture(): Future<T> {
val promise = Promise.promise<T>()
invokeOnCompletion {
try {
promise.complete(getCompleted())
} catch (t: Throwable) {
promise.fail(t)
}
}
return promise.future()
.onComplete { result ->
cancel(result.cause()?.let {
it as? CancellationException ?: CancellationException("Future was completed exceptionally", it)
})
}
}
I wonder if mixing coroutines in with Vert.x could hurt performance because you're not using the Vert.x thread pools. Maybe you can create a Dispatchers.Vertx
that borrows its thread pools.
CodePudding user response:
Vert.x Future has a conversion method:
future = Future.fromCompletionStage(completionStage, vertxContext)