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()
}