vert-x3 / vertx-lang-kotlin

Vert.x for Kotlin
Apache License 2.0
296 stars 68 forks source link

Provide a vertxFuture coroutine builder #209

Closed rgmz closed 1 year ago

rgmz commented 3 years ago

Describe the feature

In addition to the existing helper methods and builders, it would be useful to provide a coroutine builder that returns a Future<T>.

Example:

// MyService is a service proxy.
class JokeServiceImpl: JokeService {
    override fun fetchJokes(): Future<JsonArray> = future {
        // Suspending methods can be used here to fetch the data.
        jsonArray()
    }
}

// Sub-par implementation; shouldn't actually be used.
fun <T> future(block: suspend () -> T) : Future<T> {
    val dispatcher = Vertx.currentContext().dispatcher()
    val promise = Promise.promse<T>()
    try {
        // Some magic to run this in a CoroutineScope / Vertx dispatcher.
        launch {
            promise.complete(block())
        }
    } catch (ex: Exception) {
        promise.fail(ex)
    }
    return promise.future
}

Use cases

Presently, writing code that bridges coroutines and future (e.g. service proxies) can be awkward. You need to create a Promise, launch a coroutine, and handle completion of the promise:

class JokeServiceImpl(private val vertx: Vertx) : JokeService {
    override fun fetchJokes(): Future<JsonArray> {
        val promise = Promise.promise<JsonArray>()

        launch {
            try {
               val jokes: JsonArray = TODO() // suspending code to fetch jokes
               promise.complete(jokes)
            } catch (ex: Exception) {
               promise.fail(ex)
            }
        }
        return promise.future
    }
}

The kotlin.coroutines project includes several helper functions similar to this.

For example:

tsegismont commented 1 year ago

@rgmz I've created #228

Not sure why you call the implementation "sub-par", anyway feel free to comment in the PR

rgmz commented 1 year ago

Thanks @tsegismont!

I don't recall why I said that. I probably meant "I have no idea if this is valid, please don't copy and paste it into your code and assume it works."