From 68df39a4c6cf6ad831e5c91b5b29217810317a24 Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Wed, 15 Feb 2023 20:15:21 +0800 Subject: [PATCH 1/4] #2504,#2488 handle TimeoutCancellationException when resuming connection --- ...AbstractKeepAliveNetworkHandlerSelector.kt | 7 +++ .../impl/common/CommonNHBotNormalLoginTest.kt | 46 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/mirai-core/src/commonMain/kotlin/network/handler/selector/AbstractKeepAliveNetworkHandlerSelector.kt b/mirai-core/src/commonMain/kotlin/network/handler/selector/AbstractKeepAliveNetworkHandlerSelector.kt index c89b77f66a7..0a326a85736 100644 --- a/mirai-core/src/commonMain/kotlin/network/handler/selector/AbstractKeepAliveNetworkHandlerSelector.kt +++ b/mirai-core/src/commonMain/kotlin/network/handler/selector/AbstractKeepAliveNetworkHandlerSelector.kt @@ -158,6 +158,13 @@ internal abstract class AbstractKeepAliveNetworkHandlerSelector("test Connection reset by peer") { bot.login() } + assertState(NetworkHandler.State.CLOSED) + } + // 经过 #1963 考虑后在初次登录遇到任何错误都终止并传递异常 // @Test // fun `test network broken`() = runBlockingUnit { @@ -118,4 +134,34 @@ internal class CommonNHBotNormalLoginTest : AbstractCommonNHTest() { assertState(NetworkHandler.State.OK) } + + // #2504, #2488 + @Test + fun `test resume failed with TimeoutCancellationException`() = runBlockingUnit { + var first = true + var failCount = 3 + setSsoProcessor { + if (first) { + first = false + } else { + if (failCount > 0) { + failCount-- + //Throw TimeoutCancellationException + withTimeout(1) { + delay(1000) + } + } + } + } + val preTimes = bot.configuration.reconnectionRetryTimes + bot.configuration.reconnectionRetryTimes = 20 + bot.login() + bot.network.close(HeartbeatFailedException("Heartbeat Timeout", RuntimeException("Timeout stub"), true)) + eventDispatcher.joinBroadcast() + delay(1000L) // auto resume in BotOfflineEventMonitor + eventDispatcher.joinBroadcast() + bot.configuration.reconnectionRetryTimes = preTimes + assertState(NetworkHandler.State.OK) + } + } From f4bb813834345fef46e9dc288b00415fedf9a988 Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Sun, 19 Feb 2023 13:09:36 +0800 Subject: [PATCH 2/4] Remove unnecessary code and fix wording --- .../kotlin/network/impl/common/CommonNHBotNormalLoginTest.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHBotNormalLoginTest.kt b/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHBotNormalLoginTest.kt index d39957aa41b..987d5680a8b 100644 --- a/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHBotNormalLoginTest.kt +++ b/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHBotNormalLoginTest.kt @@ -103,7 +103,7 @@ internal class CommonNHBotNormalLoginTest : AbstractCommonNHTest() { delay(1000) } } - assertFailsWith("test Connection reset by peer") { bot.login() } + assertFailsWith("test TimeoutCancellationException") { bot.login() } assertState(NetworkHandler.State.CLOSED) } @@ -153,14 +153,11 @@ internal class CommonNHBotNormalLoginTest : AbstractCommonNHTest() { } } } - val preTimes = bot.configuration.reconnectionRetryTimes - bot.configuration.reconnectionRetryTimes = 20 bot.login() bot.network.close(HeartbeatFailedException("Heartbeat Timeout", RuntimeException("Timeout stub"), true)) eventDispatcher.joinBroadcast() delay(1000L) // auto resume in BotOfflineEventMonitor eventDispatcher.joinBroadcast() - bot.configuration.reconnectionRetryTimes = preTimes assertState(NetworkHandler.State.OK) } From 6b847fc9623e99abc31d94c26e2e593d13335100 Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Sun, 19 Feb 2023 13:42:47 +0800 Subject: [PATCH 3/4] Use yield() instead of delay --- .../network/impl/common/CommonNHBotNormalLoginTest.kt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHBotNormalLoginTest.kt b/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHBotNormalLoginTest.kt index 987d5680a8b..c7ffa6d8fc7 100644 --- a/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHBotNormalLoginTest.kt +++ b/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHBotNormalLoginTest.kt @@ -12,10 +12,7 @@ package net.mamoe.mirai.internal.network.impl.common import io.ktor.utils.io.errors.* -import kotlinx.coroutines.TimeoutCancellationException -import kotlinx.coroutines.delay -import kotlinx.coroutines.isActive -import kotlinx.coroutines.withTimeout +import kotlinx.coroutines.* import net.mamoe.mirai.internal.BotAccount import net.mamoe.mirai.internal.MockConfiguration import net.mamoe.mirai.internal.QQAndroidBot @@ -129,7 +126,7 @@ internal class CommonNHBotNormalLoginTest : AbstractCommonNHTest() { bot.network.close(StatSvc.ReqMSFOffline.MsfOfflineToken(0, 0, 0)) eventDispatcher.joinBroadcast() - delay(1000L) // auto resume in BotOfflineEventMonitor + yield() // auto resume in BotOfflineEventMonitor eventDispatcher.joinBroadcast() assertState(NetworkHandler.State.OK) From 74e33958e74b85138941357ca27768a24f4abb6d Mon Sep 17 00:00:00 2001 From: sandtechnology Date: Sun, 19 Feb 2023 13:44:00 +0800 Subject: [PATCH 4/4] Use yield() instead of delay --- .../kotlin/network/impl/common/CommonNHBotNormalLoginTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHBotNormalLoginTest.kt b/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHBotNormalLoginTest.kt index c7ffa6d8fc7..84491359d1b 100644 --- a/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHBotNormalLoginTest.kt +++ b/mirai-core/src/commonTest/kotlin/network/impl/common/CommonNHBotNormalLoginTest.kt @@ -153,7 +153,7 @@ internal class CommonNHBotNormalLoginTest : AbstractCommonNHTest() { bot.login() bot.network.close(HeartbeatFailedException("Heartbeat Timeout", RuntimeException("Timeout stub"), true)) eventDispatcher.joinBroadcast() - delay(1000L) // auto resume in BotOfflineEventMonitor + yield() // auto resume in BotOfflineEventMonitor eventDispatcher.joinBroadcast() assertState(NetworkHandler.State.OK) }