Start Ktor Server at a Random Port and Block for Termination

Start Ktor Server at a Random Port and Block for Termination

When I was working on my small project swagger-ui launcher, I need Ktor server starts at a random port and blocks for termination.

It's very easy to start Ktor server at a random port, simply pass 0 to the port parameter when creating the server.

val server = embeddedServer(CIO, port = 0, host = "localhost") {
    
}.start()

Since I need to get the used random port, the wait parameter of start() method is set to false. The used port can be retrieved using server.resolvedConnectors()[0].port. This code needs to be wrapped in a runBlocking block.

runBlocking {
    val port = server.resolvedConnectors()[0].port
    logger.info("Server started at port $port")
}

The last task is to block the server and wait for termination. I used a channel to support this. In the runBlocking block, exitChannel.receive() blocks until this channel receives a value. Runtime.getRuntime().addShutdownHook registers a shutdown hook which sends a value to exitChannel. When the server receives a shutdown signal (Ctrl + C), the runBlocking block unblocks and allows the server to shutdown.

val exitChannel = Channel<Boolean>(1)
Runtime.getRuntime().addShutdownHook(Thread {
    runBlocking {
        logger.info("Shutting down the server")
        exitChannel.send(true)
    }
})
runBlocking {
    exitChannel.receive()
}
© 2023 VividCode