Fix blocking call in shutdown hook

This commit is contained in:
Him188 2020-08-01 23:13:49 +08:00
parent 5efa4824bf
commit 30e359c282
3 changed files with 63 additions and 53 deletions

View File

@ -9,9 +9,8 @@
package net.mamoe.mirai.console.command package net.mamoe.mirai.console.command
import kotlinx.coroutines.cancel
import kotlinx.coroutines.cancelAndJoin import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.isActive
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
@ -86,12 +85,6 @@ public object BuiltInCommands {
ConsoleCommandOwner, "help", ConsoleCommandOwner, "help",
description = "Gets help about the console." description = "Gets help about the console."
), BuiltInCommand { ), BuiltInCommand {
init {
Runtime.getRuntime().addShutdownHook(thread(false) {
runBlocking { Stop.execute(ConsoleCommandSender.instance) }
})
}
@Handler @Handler
public suspend fun CommandSender.handle() { public suspend fun CommandSender.handle() {
sendMessage("现在有指令: ${allRegisteredCommands.joinToString { it.primaryName }}") sendMessage("现在有指令: ${allRegisteredCommands.joinToString { it.primaryName }}")
@ -105,57 +98,56 @@ public object BuiltInCommands {
), BuiltInCommand { ), BuiltInCommand {
init { init {
Runtime.getRuntime().addShutdownHook(thread(false) { Runtime.getRuntime().addShutdownHook(thread(false) {
if (!MiraiConsole.isActive) { MiraiConsole.cancel()
return@thread
}
runBlocking { Stop.execute(ConsoleCommandSender.instance) }
}) })
} }
private val closingLock = Mutex() private val closingLock = Mutex()
@Handler @Handler
public suspend fun CommandSender.handle(): Unit = closingLock.withLock { public suspend fun CommandSender.handle(): Unit {
sendMessage("Stopping mirai-console") closingLock.withLock {
kotlin.runCatching { sendMessage("Stopping mirai-console")
MiraiConsole.job.cancelAndJoin() kotlin.runCatching {
}.fold( MiraiConsole.job.cancelAndJoin()
onSuccess = { sendMessage("mirai-console stopped successfully.") }, }.fold(
onFailure = { onSuccess = { sendMessage("mirai-console stopped successfully.") },
MiraiConsole.mainLogger.error(it) onFailure = {
sendMessage(it.localizedMessage ?: it.message ?: it.toString()) MiraiConsole.mainLogger.error(it)
} sendMessage(it.localizedMessage ?: it.message ?: it.toString())
) }
)
}
exitProcess(0) exitProcess(0)
} }
}
public object Login : SimpleCommand( public object Login : SimpleCommand(
ConsoleCommandOwner, "login", ConsoleCommandOwner, "login",
description = "Log in a bot account." description = "Log in a bot account."
), BuiltInCommand { ), BuiltInCommand {
@Handler @Handler
public suspend fun CommandSender.handle(id: Long, password: String) { public suspend fun CommandSender.handle(id: Long, password: String) {
kotlin.runCatching { kotlin.runCatching {
MiraiConsole.addBot(id, password).alsoLogin() MiraiConsole.addBot(id, password).alsoLogin()
}.fold( }.fold(
onSuccess = { sendMessage("${it.nick} ($id) Login succeed") }, onSuccess = { sendMessage("${it.nick} ($id) Login succeed") },
onFailure = { throwable -> onFailure = { throwable ->
sendMessage( sendMessage(
"Login failed: ${throwable.localizedMessage ?: throwable.message ?: throwable.toString()}" + "Login failed: ${throwable.localizedMessage ?: throwable.message ?: throwable.toString()}" +
if (this is MessageEventContextAware<*>) { if (this is MessageEventContextAware<*>) {
this.fromEvent.selectMessagesUnit { this.fromEvent.selectMessagesUnit {
"stacktrace" reply { "stacktrace" reply {
throwable.stacktraceString throwable.stacktraceString
}
} }
} "test"
"test" } else "")
} else "")
throw throwable throw throwable
} }
) )
}
} }
} }
} }

View File

@ -11,7 +11,23 @@
package net.mamoe.mirai.console.command package net.mamoe.mirai.console.command
import kotlinx.coroutines.cancel
import kotlinx.coroutines.runBlocking
import net.mamoe.mirai.console.MiraiConsole
import net.mamoe.mirai.console.Testing import net.mamoe.mirai.console.Testing
import net.mamoe.mirai.console.Testing.withTesting
import net.mamoe.mirai.console.command.description.CommandArgParser
import net.mamoe.mirai.console.command.description.CommandParserContext
import net.mamoe.mirai.console.command.internal.InternalCommandManager
import net.mamoe.mirai.console.command.internal.flattenCommandComponents
import net.mamoe.mirai.console.initTestEnvironment
import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.message.data.SingleMessage
import net.mamoe.mirai.message.data.toMessage
import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import kotlin.test.*
object TestCompositeCommand : CompositeCommand( object TestCompositeCommand : CompositeCommand(
ConsoleCommandOwner, ConsoleCommandOwner,
@ -33,7 +49,7 @@ object TestSimpleCommand : RawCommand(owner, "testSimple", "tsS") {
internal val sender by lazy { ConsoleCommandSender.instance } internal val sender by lazy { ConsoleCommandSender.instance }
internal val owner by lazy { ConsoleCommandOwner } internal val owner by lazy { ConsoleCommandOwner }
/*
internal class TestCommand { internal class TestCommand {
companion object { companion object {
@JvmStatic @JvmStatic
@ -45,8 +61,7 @@ internal class TestCommand {
@AfterAll @AfterAll
@JvmStatic @JvmStatic
fun destroy() { fun destroy() {
// Runtime.getRuntime().halt(0) // TODO: 2020/8/1 fix exitProcess MiraiConsole.cancel()
exitProcess(0)
} }
} }
@ -209,4 +224,3 @@ internal class TestCommand {
} }
} }
} }
*/

View File

@ -9,7 +9,12 @@
package net.mamoe.mirai.console.setting package net.mamoe.mirai.console.setting
/* import kotlinx.serialization.json.Json
import net.mamoe.mirai.console.utils.ConsoleInternalAPI
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
import kotlin.test.assertSame
@OptIn(ConsoleInternalAPI::class) @OptIn(ConsoleInternalAPI::class)
internal class SettingTest { internal class SettingTest {
@ -129,4 +134,3 @@ internal class SettingTest {
assertSame(reference(), delegation()) // check shadowing assertSame(reference(), delegation()) // check shadowing
} }
} }
*/