in kotlin-native .. what is the correct way to sta...
# ktor
n
in kotlin-native .. what is the correct way to start ktor so that i can shut it down from a signal handler? seems like doing
server.start(wait = true)
will just block my application completely when i call
server.stop(500, 500)
not sure why.. could it be that joining the jobs is blocking ? for now i am using this..
Copy code
server = embeddedServer(...)

server.start(wait = false)

while (true) {
    sleep(1)
}
and in the signal handler i call
Copy code
server.stop(500, 500)
if anybody knows a cleaner solution.. would like to make this work better i also noticed.. if i use
delay
instead of sleep it will also continue to block..?
h
What about using coroutines?
Copy code
coroutineScope {
  val server = embeddedServer(..)
  server.start(wait = false)

  action()
  server.stop()
}

suspend fun action() = suspendCoroutine { cont ->
  registerSignalHandler(callback = {
    cont.resume()
  })
}
n
this works nicely if i understand this correctly it stops at the end of
suspendCoroutine
until the signal handler triggers the continuation ?
h
Yes
e
IMO it would be safer to use a semaphore,
Copy code
val stopSignal = Semaphore(1, 1)
registerSignalHandler { stopSignal.release() }
coroutineScope {
    ...
    stopSignal.acquire()
}
note that in both solutions, your program will crash if the signal handler is invoked multiple times. you can use a
CompletableDeferred
instead if that is a concern
n
upon some more experimenting i found this solution..
Copy code
val completableJob = SupervisorJob()
SignalHandler.onSignal(SIGINT) { _, signalName ->
    logger.warn { "received signal $signalName, stopping server.." }
    // completableJob.complete() // this will cause it to hang
    completableJob.cancel()
}
embeddedServer(
    factory = CIO,
    host = serverOptions.host,
    port = serverOptions.port,
    logger = KtorKLogger(),
    parentCoroutineContext = completableJob
) {
    configureHTTP()
    configureRouting()
}.start(true)
on a sidenote.. ith all these solutions there seems to be the problem that after the interrupt.. any
println
or logging calls seem to disappear might be a problem caused by interrupting.. i wonder.. what mistake i am overlooking.. PS: found that using cancel will work..
but i really like the solution using a
CompletableDeferred
too