How to express non functional concerns using kotlin DSL
Tags: kotlin, dsl, resiliency
Published: 2019-01-28 03:04:15

---
title: How to express non functional concerns using kotlin DSL
published: true
description: 
tags: kotlin, dsl, resiliency
---

#Kotlin DSL support is awesome!

One of my favorites features of Kotlin, is the powerful DSL(ish) support the language provides.

You can write very expressive functions that look almost like a DSL, all because in Kotlin if the last argument of a function is a lambda you can move it outside the parentheses into curly brackets `{}`

This allows you to write code that almost look like a markdown representation such as the `HTML` builder that ships with the language:
```
html {
        head {
            title {+"XML encoding with Kotlin"}
        }
        body { }
}
```

This code looks like a markdown, but it's a static compiled piece of code. Isn't that nice?

One of my favorites usages of DSLs in kotlin is a project that wraps kubernetes-client (which uses a lot of builders) into nice friendly DSL. Check it out: [k8s-kotlin-dsl](https://github.com/fkorotkov/k8s-kotlin-dsl)

#How I got addicted to it

After a while I started to using DSLs more and more. If you use co-routines you probably saw this DSL-esque function:
```kotlin
fun testAsyncFunction() = runBlocking {
//Some async code goes here
}
``` 
Another one that I enjoy quite a lot is to replace all those: `System.currentTimeInMillis()` we all have on our code:

```kotlin
val runningTime = measureTimeInMillis {
//invoke function here
}

```

As you can see, using DSLs can make your code easier to read, one can easily infer what is happening at `measureTimeInMillis` or in `runBlocking`

So because of that I started creating a few of my own.

#Being a nice API consumer

Another area where Kotlin shines is concurrency with co-routines (as well as parallelism with async). 

In one of my pet projects I crawl an external public API that has a rate-limit policy. No limits, as long as you space your calls every 2 seconds.

Since I create a gazillion co-routines (actually more like 3k) and I want them to run in parallel not writing a `delay(2000)` on each function. I decided to use an implementation of a [TokenBucket - Wikipedia](https://en.wikipedia.org/wiki/Token_bucket) : [Github repo](https://github.com/bbeck/token-bucket).

So I wanted all my functions that were running inside an `async` block to be *limited* by a given tokenbucket. So the idea was that any function should look like this:

```kotlin
fun request() : ApiResponse<T> = limited {

}
```

This would allow anyone reading this code to see that this call, is limited by a certain factor.

The limited function is very simple:

```kotlin
suspend fun <T> limited(bucket: TokenBucket = DEFAULT_LIMITER,  block: suspend () -> T) : T {
    bucket.consume()
    return block()
}
```

The block parameter is the function you are wrapping between `limited { <block> }`, which returns whatever the type your original function returns. We call this higher order functions.

Because all the code is supposed to run on a suspended state, both the function and the block are marked as `suspend`.

Now I can run this code inside a loop like this:

```kotlin
val pages = getNumberOfPages()
for(p in 0..pages){

GlobalScope.launch {
val response request(p)
//process response
}

//return immediately to caller


```

And I'm sure that all thousands of jobs in flight will be limited by only 1 call every 2 seconds.

#Final thoughts

It's becoming pretty easy to understand why kotlin is such a beloved language. Small features like this make your code so much more readable. It's pretty neat to be able to express your code in a clear way.

Happy coding