Skip to content

Commit 6a7f189

Browse files
authored
fix(yogurt): repair Linux shutdown (#33)
* fix(yogurt): use platform specific shutdown on Linux * fix(yogurt): use `posix.signal` on Linux
1 parent 1d27ddf commit 6a7f189

File tree

7 files changed

+65
-3
lines changed

7 files changed

+65
-3
lines changed

yogurt/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ plugins {
88
id("buildsrc.convention.kotlin-multiplatform")
99
alias(libs.plugins.kotlin.serialization)
1010
alias(libs.plugins.build.konfig)
11+
alias(libs.plugins.kotlinx.atomicfu)
1112
}
1213

1314
version = "0.1.0"

yogurt/src/commonMain/kotlin/org/ntqqrev/yogurt/Main.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22

33
package org.ntqqrev.yogurt
44

5-
import io.ktor.server.engine.*
5+
import kotlinx.coroutines.delay
6+
import kotlinx.coroutines.runBlocking
67
import kotlin.jvm.JvmName
78

89
fun main() {
910
val server = YogurtApp.createServer()
10-
server.addShutdownHook {
11+
server.start(wait = false)
12+
server.onSigint {
1113
server.stop(gracePeriodMillis = 2000L, timeoutMillis = 5000L)
1214
}
13-
server.start(wait = true)
15+
runBlocking {
16+
delay(Long.MAX_VALUE)
17+
}
1418
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.ntqqrev.yogurt
2+
3+
import io.ktor.server.engine.EmbeddedServer
4+
5+
expect fun EmbeddedServer<*, *>.onSigint(hook: () -> Unit)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.ntqqrev.yogurt
2+
3+
import io.ktor.server.engine.*
4+
5+
actual fun EmbeddedServer<*, *>.onSigint(hook: () -> Unit) {
6+
addShutdownHook(hook)
7+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.ntqqrev.yogurt
2+
3+
import io.ktor.server.engine.*
4+
import io.ktor.server.plugins.di.dependencies
5+
import kotlinx.atomicfu.atomic
6+
import kotlinx.cinterop.ExperimentalForeignApi
7+
import kotlinx.cinterop.staticCFunction
8+
import kotlinx.coroutines.runBlocking
9+
import org.ntqqrev.acidify.AbstractBot
10+
import org.ntqqrev.acidify.offline
11+
import platform.posix.SIGINT
12+
import platform.posix.exit
13+
import platform.posix.signal
14+
15+
val botRef = atomic<AbstractBot?>(null)
16+
17+
@OptIn(ExperimentalForeignApi::class)
18+
actual fun EmbeddedServer<*, *>.onSigint(hook: () -> Unit) {
19+
botRef.value = runBlocking { application.dependencies.resolve<AbstractBot>() }
20+
// On Linux targets, the shutdown hook gets unexpectedly overridden by Ktor's internal shutdown hook;
21+
// and `server.stop()` blocks forever on Linux,
22+
// so we have to use a `exit(0)` to force the process to exit immediately after the shutdown hook is executed.
23+
// See KTOR-9308 and KTOR-9309 for more details.
24+
signal(SIGINT, staticCFunction { _ ->
25+
println("Received SIGINT, shutting down...")
26+
runBlocking {
27+
botRef.value?.offline()
28+
}
29+
exit(0)
30+
})
31+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.ntqqrev.yogurt
2+
3+
import io.ktor.server.engine.*
4+
5+
actual fun EmbeddedServer<*, *>.onSigint(hook: () -> Unit) {
6+
addShutdownHook(hook)
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.ntqqrev.yogurt
2+
3+
import io.ktor.server.engine.*
4+
5+
actual fun EmbeddedServer<*, *>.onSigint(hook: () -> Unit) {
6+
addShutdownHook(hook)
7+
}

0 commit comments

Comments
 (0)