Vert.x Kotlin Coroutines

Frank Rosner on February 13, 2019

Vert.x Eclipse Vert.x is an event-driven application framework that runs on the JVM. Architecturally it is very similar to Node.js, ha... [Read Full]
markdown guide
 

Amongst other issues, callbacks were the main reason not to use vert.x when vert.x 2 came out, I wrote an article about why i wouldn’t use it in production. A couple of things have been fixed with 3 but callback still made code unnecessarily unreadable for the simplest tasks. In that article suggested using coroutines, so i’m quite happy to see it. However, it’s still not available to Java. But maybe that’s one more reason to think about switching to Kotlin... 😉

 

Hi! Thanks for the comment :)

Would you mind sharing a link to your article?

 

Sure, here it is:
return.co.de/blog/articles/vertx-b...

The fun-fact is, that lager parts of my company used vert.x for 2-3 year. I strictly opposed and my team used spring boot and the recent reactive webflux. Now, all new services will be built using spring boot/webflux.

For simple CRUD style APIs with relational DBs, reactive just makes everything much more complicated without any benefit.

We have one or two services, that are doing heavy event lifting where reactive style makes sense.
And I am definitely a fan of the actor model and immutable messaging. However, I simply don’t like callbacks and obserables and such...

 

A question: Vertx dispatches 1 eventloop in a single thread, and dispatches 1 eventloop for each processor core (please correct me if I remember wrong).

The event loop works already in an asynchronous and non blocking way: if you block an operation you get a warning from the framework.

So I don't understand the necessity to create an async layer (the coroutine) over another async layer (the event loop).

Am I missing some piece or I have misunderstood any concept? Can you clarify?

 

Hi Marco!

I don't think you misunderstood and this is an excellent question.

Coroutines themselves are another layer on top of the event callbacks. So you are wrapping the callback based API inside coroutines in order to enable composition of asynchronous functions through Coroutines rather than callback chains.

This does not necessarily mean that the coroutines are executed outside of the event loop. While you can use a different coroutine context (e.g. runBlocking when starting your Vert.x web server to make sure to resume only as soon as it is started), most of the cases your coroutines will run through the Vert.x dispatcher.

Let's say we are building a web application and we want to write our handlers as coroutines. We can do that with a simple helper function:

fun coroutineHandler(route: Route, handler: suspend (RoutingContext) -> Unit) {
    route.handler { ctx ->
        launch(ctx.vertx().dispatcher()) {
            try {
                handler(ctx)
            } catch (e: Exception) {
                log.error("Coroutine handler failed: $e")
                ctx.fail(e)
            }
        }
    }
}

With this helper we can add handlers to routes that do not take a callback but are suspending functions instead. The coroutine itself however will be launched through the Vert.x dispatcher of the routing context, so no new execution layer is added on top.

Inside your coroutine handlers you can then, e.g., use the Vert.x web client which has different sendAwait methods thanks to Vert.x Kotlin Coroutines so they will not block your event thread.

I hope it became clearer now. Please let me know if my explanation made sense and if you have more questions :)

 
 

Nice post!

I worked with Vert.x in the past and it was a pain.

I like Javascript async/await style and I find this very similar.

code of conduct - report abuse