1
0
mirror of https://github.com/mamoe/mirai.git synced 2025-04-25 21:12:40 +08:00

Broadcast BotOfflineEvent async and ensure joinBroadcast works for it

This commit is contained in:
Him188 2022-05-13 22:54:10 +01:00
parent da65f4d86d
commit bdf125e26d
5 changed files with 36 additions and 10 deletions
mirai-core/src

View File

@ -11,9 +11,9 @@
package net.mamoe.mirai.internal
import kotlinx.atomicfu.atomic
import kotlinx.coroutines.isActive
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.*
import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.BotOfflineEvent
import net.mamoe.mirai.event.events.BotOnlineEvent
import net.mamoe.mirai.event.events.BotReloginEvent
@ -148,7 +148,17 @@ internal open class QQAndroidBot constructor(
cause is BotClosedByEvent -> {}
else -> {
// any other unexpected exceptions considered as an error
runBlocking { eventDispatcher.broadcast(BotOfflineEvent.Active(bot, cause)) }
// When bot is closed, eventDispatcher.isActive will be false.
// While in TestEventDispatcherImpl, eventDispatcher.isActive will always be true to enable catching the event.
if (eventDispatcher.isActive) {
eventDispatcher.broadcastAsync { BotOfflineEvent.Active(bot, cause) }
} else {
@OptIn(DelicateCoroutinesApi::class)
GlobalScope.launch {
BotOfflineEvent.Active(bot, cause).broadcast()
}
}
}
}
},

View File

@ -22,6 +22,8 @@ import kotlin.coroutines.EmptyCoroutineContext
* All events will be caught and forwarded to [EventDispatcher]. Invocation of [Event.broadcast] and [EventDispatcher.broadcast] are effectively equal.
*/
internal interface EventDispatcher {
val isActive: Boolean
/**
* Implement [Event.broadcast]
*/
@ -91,6 +93,9 @@ internal open class EventDispatcherImpl(
.addNameHierarchically("EventDispatcher")
.childScope() {
override val isActive: Boolean
get() = this.coroutineContext.isActive
override suspend fun broadcast(event: Event) {
try {
EventChannelToEventDispatcherAdapter.instance.callListeners(event)

View File

@ -1,16 +1,17 @@
/*
* Copyright 2019-2021 Mamoe Technologies and contributors.
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/master/LICENSE
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/
@file:Suppress("MemberVisibilityCanBePrivate")
package net.mamoe.mirai.internal.network.framework
import kotlinx.coroutines.SupervisorJob
import net.mamoe.mirai.Bot
import net.mamoe.mirai.internal.MockBot
import net.mamoe.mirai.internal.QQAndroidBot
@ -45,7 +46,12 @@ internal abstract class AbstractMockNetworkHandlerTest : AbstractNetworkHandlerT
set(SsoProcessor, TestSsoProcessor(bot))
set(
EventDispatcher,
TestEventDispatcherImpl(bot.coroutineContext, bot.logger.subLogger("TestEventDispatcherImpl"))
// Note that in real we use 'bot.coroutineContext', but here we override with a new, independent job
// to allow BotOfflineEvent.Active to be broadcast and joinBroadcast works even if bot coroutineScope is closed.
TestEventDispatcherImpl(
bot.coroutineContext + SupervisorJob(),
bot.logger.subLogger("TestEventDispatcherImpl")
)
)
set(
StateObserver,

View File

@ -9,6 +9,7 @@
package net.mamoe.mirai.internal.network.framework
import kotlinx.coroutines.SupervisorJob
import net.mamoe.mirai.internal.BotAccount
import net.mamoe.mirai.internal.MockAccount
import net.mamoe.mirai.internal.MockConfiguration
@ -131,7 +132,12 @@ internal sealed class AbstractRealNetworkHandlerTest<H : NetworkHandler> : Abstr
set(
EventDispatcher,
TestEventDispatcherImpl(bot.coroutineContext, bot.logger.subLogger("TestEventDispatcherImpl"))
// Note that in real we use 'bot.coroutineContext', but here we override with a new, independent job
// to allow BotOfflineEvent.Active to be broadcast and joinBroadcast works even if bot coroutineScope is closed.
TestEventDispatcherImpl(
bot.coroutineContext + SupervisorJob(),
bot.logger.subLogger("TestEventDispatcherImpl")
)
)
// set(StateObserver, bot.run { stateObserverChain() })
}

View File

@ -10,7 +10,6 @@
package network.framework.components
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.isActive
import kotlinx.coroutines.job
import kotlinx.coroutines.launch
import net.mamoe.mirai.event.Event