EventDispatcher: launch Jobs UNDISPATCHED-ly

This commit is contained in:
Him188 2021-05-30 23:57:25 +08:00
parent 76eaa34917
commit ff6c63fafc
3 changed files with 22 additions and 7 deletions

View File

@ -9,10 +9,7 @@
package net.mamoe.mirai.internal.network.components
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.job
import kotlinx.coroutines.launch
import kotlinx.coroutines.*
import net.mamoe.mirai.event.Event
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.internal.network.component.ComponentKey
@ -65,7 +62,9 @@ internal class EventDispatcherImpl(
}
override fun broadcastAsync(event: Event, additionalContext: CoroutineContext): EventBroadcastJob {
val job = launch(additionalContext) { broadcast(event) }
val job = launch(additionalContext, start = CoroutineStart.UNDISPATCHED) { broadcast(event) }
// UNDISPATCHED: starts the coroutine NOW in the current thread until its first suspension point,
// so that after `broadcastAsync` the job is always already started and `joinBroadcast` will work normally.
return EventBroadcastJob(job)
}

View File

@ -52,4 +52,22 @@ internal class EventDispatcherTest : AbstractTest() {
dispatcher.joinBroadcast()
}
}
@Test
fun `broadcastAsync starts job immediately`() = runBlockingUnit {
assertEventBroadcasts<Ev>(1) {
dispatcher.broadcastAsync(Ev())
dispatcher.joinBroadcast()
}
}
@Test
fun `broadcastAsync starts job immediately parallel`() = runBlockingUnit {
assertEventBroadcasts<Ev>(20) {
repeat(20) {
dispatcher.broadcastAsync(Ev())
}
dispatcher.joinBroadcast()
}
}
}

View File

@ -127,8 +127,6 @@ internal class NettyHandlerEventTest : AbstractNettyNHTest() {
ok.get().complete(Unit)
network.resumeConnection()
eventDispatcher.joinBroadcast()
delay(5000) // BotReloginEvent broadcast not started now
eventDispatcher.joinBroadcast()
}.let { event ->
assertEquals(BotOnlineEvent::class, event[0]::class)
assertEquals(BotReloginEvent::class, event[1]::class)