xenomachina
06/06/2023, 6:37 AMEngineMain
, but needed to do some even earlier initialization (place some things in MDC globally), so we switched to using the embedded server.
Our main
function ended up looking something like:
fun main() {
val config = getConfig()
runBlocking() {
setupGlobalMDC(config)
withContext(MDCContext()) {
embeddedServer(Jetty, port = config.port) {
// The stuff in here used to be in the function
// referenced by ktor.application.modules
val backgroundJob = launch { backgroundWorker() }
serverSetup(config, backgroundJob)
}.start(wait = true)
}
}
}
This mostly worked, except it turned out that backgroundJob
didn't seem to be running. It's a loop that listens on a channel, and somehow it did not seem to be doing anything even when messages were sent to its channel. It worked fine before we switched to using the embedded server.
On a hunch, I tried replacing runBlocking()
with runBlocking(<http://Dispatchers.IO|Dispatchers.IO>)
. Now it works, but I don't really understand why it didn't work in the first place.
Does anyone know why <http://Dispatchers.IO|Dispatchers.IO>
is required here?Dmitry Khalanskiy [JB]
06/06/2023, 6:49 AMDmitry Khalanskiy [JB]
06/06/2023, 6:51 AMrunBlocking
, you can also pass it to launch
. Then only that job will execute on another dispatcher.CLOVIS
06/06/2023, 7:54 AMsuspend
, so you shouldn't need runBlocking
at all. My guess is serverSetup
is suspend
, but you didn't send its code so I can't tell.xenomachina
06/30/2023, 11:39 PMserverSetup
is suspend
. Additionally, embeddedServer
is a extension function on CoroutineScope
. In the real code the launch is actually inside that function.
I think your answer gave me a better idea about what's going on, and why using <http://Dispatchers.IO|Dispatchers.IO>
"fixes" it, though it also makes me think that's not really the correct way to accomplish this.
I looked in ktor's EngineMain, and saw that it seems to use construct a dispatcher out of Jetty's thread pool. Unfortunately, there doesn't seem to be any way to mimic this when using embeddedServer
. However, I saw that embeddedServer
has an overload that uses GlobalScope
, so I tried switching to that, and it works as desired.
Thank you both!