0

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 !

Ahmet K
  • 713
  • 18
  • 42

2 Answers2

3

Vert.x Future has a conversion method:

future = Future.fromCompletionStage(completionStage, vertxContext)
tsegismont
  • 8,591
  • 1
  • 17
  • 27
0

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.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • Vertx provides a dispatcher: https://vertx.io/docs/vertx-lang-kotlin-coroutines/kotlin/#_running_a_coroutine_from_a_vert_x_context – dano Dec 07 '21 at 20:30
  • How would that look like then ? – Ahmet K Dec 07 '21 at 20:32
  • @AhmetKazaman I've used Vert.x quite a bit, but I haven't used Kotlin with it, so I don't know the answer. I would have guessed that the documentation on the page I linked to would provide enough guidance for someone more familiar with Kotlin to figure out the answer (my suspicion is that you shouldn't need a `CompletableFuture` at all to do what the OP is trying to do), but I'm really not sure! – dano Dec 07 '21 at 20:48
  • Yes, I think you would only need this above function under certain circumstances. If you're using coroutines in your project and not working with legacy code or an API that demands Future to be used, it would be more natural to directly pass around your Kotlin Deferred or simply use suspend functions. And I would use the dispatcher @dano linked when using coroutines to work with Vert.x. – Tenfour04 Dec 07 '21 at 21:15