Kotlin 1.3 is in RC and will be released soon, so I thought it is a good time to give it a spin with coroutines and ktor that will be graduating out of experimental mode with the GA. With all that and jasync-sql (That I am working on) it is possible to write async backend that looks sequential.

With ktor, coroutines, and jasync-sql it is possible to create a complete async backend, written in sequential style but without blocking threads during requests from the user all the way up to the database.

How does it work?

The interesting part happens in ktor on the routing block. First, we would like to just call connection.sendPreparedStatement(query) . However, The method returns CompletableFuture . To overcome this kotlinx.coroutines provide us a transformation from CompletableFuture to suspend method via jdk-8 integration package. The conversion method is called await .

With that in hand we can easily create a cool extension method on connection to do what we wanted the first place:

suspend fun Connection.sendPreparedStatementAwait(

query: String,

values: List<Any>): QueryResult =

sendPreparedStatement(query, values).await()

What’s left is just to put the value in the response :

call.respond(QueryResult.row[0].toString())

Connections pool

On one hand, we don’t want to create a connection for each query execution. On the other hand, a connection can only execute one query at a time.

The solution for that is to use a ConnectionPool . It has the same interface of a Connection with a specified configuration:

maxObjects — the number of simultaneous connection.

— the number of simultaneous connection. maxQueueSize — the number of pending queries.

— the number of pending queries. maxIdle — the millisecond before an idle connection is reclaimed.

— the millisecond before an idle connection is reclaimed. validationInterval — interval in milliseconds to ping the server to make sure connection is ready.

This is the configuration I used:

val poolConfiguration = PoolConfiguration(

maxObjects = 100,

maxQueueSize = 10_000,

maxIdle = TimeUnit.MINUTES.toMillis(15),

validationInterval = TimeUnit.SECONDS.toMillis(30)

That’s all

I have placed all the code in GitHub:

Hope you will find it helpful!