From 7dd4a9669bcc9ba246075fdd3acb36fcaa5d5174 Mon Sep 17 00:00:00 2001 From: Karlatemp <karlatemp@vip.qq.com> Date: Thu, 12 Nov 2020 12:38:49 +0800 Subject: [PATCH] Fix console stopping, fix #221 - Make StopCommand async - Close terminal reader only --- .../src/command/BuiltInCommands.kt | 46 ++++++++++--------- backend/mirai-console/src/util/SemVersion.kt | 4 +- .../src/ConsoleThread.kt | 10 ++-- 3 files changed, 29 insertions(+), 31 deletions(-) diff --git a/backend/mirai-console/src/command/BuiltInCommands.kt b/backend/mirai-console/src/command/BuiltInCommands.kt index c24fe9948..a5d978b53 100644 --- a/backend/mirai-console/src/command/BuiltInCommands.kt +++ b/backend/mirai-console/src/command/BuiltInCommands.kt @@ -102,29 +102,31 @@ public object BuiltInCommands { @Handler public suspend fun CommandSender.handle() { - kotlin.runCatching { - closingLock.withLock { - sendMessage("Stopping mirai-console") - kotlin.runCatching { - runIgnoreException<CancellationException> { MiraiConsole.job.cancelAndJoin() } - }.fold( - onSuccess = { - runIgnoreException<EventCancelledException> { sendMessage("mirai-console stopped successfully.") } - }, - onFailure = { - if (it is CancellationException) return@fold - @OptIn(ConsoleInternalApi::class) - MiraiConsole.mainLogger.error("Exception in stop", it) - runIgnoreException<EventCancelledException> { - sendMessage( - it.localizedMessage ?: it.message ?: it.toString() - ) + GlobalScope.launch { + kotlin.runCatching { + closingLock.withLock { + if (!MiraiConsole.isActive) return@withLock + sendMessage("Stopping mirai-console") + kotlin.runCatching { + MiraiConsole.job.cancelAndJoin() + }.fold( + onSuccess = { + runIgnoreException<EventCancelledException> { sendMessage("mirai-console stopped successfully.") } + }, + onFailure = { + @OptIn(ConsoleInternalApi::class) + MiraiConsole.mainLogger.error("Exception in stop", it) + runIgnoreException<EventCancelledException> { + sendMessage( + it.localizedMessage ?: it.message ?: it.toString() + ) + } } - } - ) - } - }.exceptionOrNull()?.let(MiraiConsole.mainLogger::error) - exitProcess(0) + ) + } + }.exceptionOrNull()?.let(MiraiConsole.mainLogger::error) + exitProcess(0) + } } } diff --git a/backend/mirai-console/src/util/SemVersion.kt b/backend/mirai-console/src/util/SemVersion.kt index f350c0f58..4aee3861d 100644 --- a/backend/mirai-console/src/util/SemVersion.kt +++ b/backend/mirai-console/src/util/SemVersion.kt @@ -94,9 +94,7 @@ internal constructor( private val impl = SemVersionInternal.parseRangeRequirement(rule) /** 在 [version] 满足此要求时返回 true */ - public fun test(version: SemVersion): Boolean { - return impl.test(version) - } + public fun test(version: SemVersion): Boolean = impl.test(version) public object RequirementAsStringSerializer : KSerializer<Requirement> by String.serializer().map( serializer = { it.rule }, diff --git a/frontend/mirai-console-terminal/src/ConsoleThread.kt b/frontend/mirai-console-terminal/src/ConsoleThread.kt index 97294ca1c..2e2e78fba 100644 --- a/frontend/mirai-console-terminal/src/ConsoleThread.kt +++ b/frontend/mirai-console-terminal/src/ConsoleThread.kt @@ -9,10 +9,7 @@ package net.mamoe.mirai.console.terminal -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.CoroutineName -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch +import kotlinx.coroutines.* import net.mamoe.mirai.console.MiraiConsole import net.mamoe.mirai.console.command.* import net.mamoe.mirai.console.command.descriptor.ExperimentalCommandDescriptors @@ -30,12 +27,13 @@ internal fun startupConsoleThread() { if (terminal is NoConsole) return MiraiConsole.launch(CoroutineName("Input Cancelling Daemon")) { - while (true) { + while (isActive) { delay(2000) } }.invokeOnCompletion { runCatching<Unit> { - terminal.close() + // 应该仅关闭用户输入 + terminal.reader().shutdown() ConsoleInputImpl.thread.shutdownNow() runCatching { ConsoleInputImpl.executingCoroutine?.cancel(EndOfFileException())