Add awaitStateChange

This commit is contained in:
Him188 2021-06-05 14:45:58 +08:00
parent c6075ec299
commit e788aa09f7
3 changed files with 36 additions and 1 deletions

View File

@ -88,4 +88,13 @@ public inline fun CoroutineContext.addNameIfAbsent(
public fun CoroutineContext.addNameHierarchically(
name: String
): CoroutineContext = this + CoroutineName(this[CoroutineName]?.name?.plus('.')?.plus(name) ?: name)
): CoroutineContext = this + CoroutineName(this[CoroutineName]?.name?.plus('.')?.plus(name) ?: name)
public fun CoroutineContext.hierarchicalName(
name: String
): CoroutineName = CoroutineName(this[CoroutineName]?.name?.plus('.')?.plus(name) ?: name)
public fun CoroutineScope.hierarchicalName(
name: String
): CoroutineName = this.coroutineContext.hierarchicalName(name)

View File

@ -13,6 +13,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.consumeAsFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.takeWhile
import net.mamoe.mirai.Bot
import net.mamoe.mirai.internal.network.Packet
@ -44,6 +45,11 @@ internal interface NetworkHandler : CoroutineScope {
*/
val state: State
fun getLastFailure(): Throwable?
/**
* The channel that is sent with a [State] when changed.
*/
val stateChannel: ReceiveChannel<State>
/**
@ -184,4 +190,8 @@ internal val NetworkHandler.logger: MiraiLogger get() = context.logger
internal suspend fun NetworkHandler.awaitState(suspendUntil: NetworkHandler.State) {
if (this.state == suspendUntil) return
stateChannel.consumeAsFlow().takeWhile { it != suspendUntil }.collect()
}
internal suspend fun NetworkHandler.awaitStateChange() {
stateChannel.consumeAsFlow().first()
}

View File

@ -17,6 +17,7 @@ import net.mamoe.mirai.internal.network.framework.AbstractMockNetworkHandlerTest
import net.mamoe.mirai.internal.network.handler.NetworkHandler
import net.mamoe.mirai.internal.network.handler.NetworkHandler.State.*
import net.mamoe.mirai.internal.network.handler.awaitState
import net.mamoe.mirai.internal.network.handler.awaitStateChange
import net.mamoe.mirai.internal.test.runBlockingUnit
import org.junit.jupiter.api.Test
import java.util.concurrent.ConcurrentLinkedQueue
@ -132,4 +133,19 @@ internal class AwaitStateTest : AbstractMockNetworkHandlerTest() {
yield()
}
}
@Test
fun `can await change`() = runBlockingUnit(singleThreadDispatcher + Job()) {
createNetworkHandler().run {
assertState(INITIALIZED)
val job = launch(start = CoroutineStart.UNDISPATCHED) {
awaitStateChange()
}
yield()
assertTrue { job.isActive }
setState(CLOSED)
yield()
}
}
}