Context in Kotlin

Here’s the translation of the Go code example to Kotlin, formatted in Markdown suitable for Hugo:

In the previous example we looked at setting up a simple HTTP server. HTTP servers are useful for demonstrating the usage of CoroutineContext for controlling cancellation. A CoroutineContext carries job, dispatchers, and other coroutine-scoped values across API boundaries and coroutines.

import kotlinx.coroutines.*
import io.ktor.application.*
import io.ktor.http.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*

fun Application.module() {
    routing {
        get("/hello") {
            println("server: hello handler started")
            try {
                withTimeout(10000) {
                    // Simulate some work
                    delay(5000)
                    call.respondText("hello\n")
                }
            } catch (e: TimeoutCancellationException) {
                println("server: ${e.message}")
                call.respond(HttpStatusCode.InternalServerError, e.message ?: "Internal Server Error")
            } finally {
                println("server: hello handler ended")
            }
        }
    }
}

fun main() {
    embeddedServer(Netty, port = 8090, module = Application::module).start(wait = true)
}

In this Kotlin example, we’re using the Ktor framework to set up a simple HTTP server. The CoroutineContext in Kotlin is analogous to the context.Context in Go, providing a way to manage coroutine lifecycles and cancellation.

  1. We define a route handler for “/hello” using Ktor’s DSL.

  2. Inside the handler, we use withTimeout to set a 10-second timeout for the operation. This is similar to the select statement with a timeout in the Go example.

  3. We simulate some work by using delay(5000) (5 seconds).

  4. If the operation completes within the timeout, we respond with “hello\n”.

  5. If a TimeoutCancellationException is caught (equivalent to the context being done in Go), we log the error and respond with an Internal Server Error.

  6. We use println for logging, which is not ideal for production but works for this example.

  7. In the main function, we start the server on port 8090.

To run the server:

$ ./gradlew run

To simulate a client request to /hello, you can use curl:

$ curl localhost:8090/hello

If you wait for the full 10 seconds, you’ll see the “hello” response. If you interrupt the curl command before that (e.g., with Ctrl+C), you’ll see the timeout error logged on the server side.

This Kotlin version demonstrates similar concepts of context and cancellation as the original example, adapted to Kotlin’s coroutine-based concurrency model.