mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-10 02:20:14 +08:00
Support refreshing instance in NetworkHandlerSelector
This commit is contained in:
parent
8c0f245da1
commit
00e2d2b77f
@ -46,6 +46,12 @@ internal abstract class AbstractKeepAliveNetworkHandlerSelector<H : NetworkHandl
|
|||||||
|
|
||||||
final override fun getResumedInstance(): H? = current.value
|
final override fun getResumedInstance(): H? = current.value
|
||||||
|
|
||||||
|
final override tailrec fun tryResumeInstanceOrCreate(): H {
|
||||||
|
getResumedInstance()?.let { return it }
|
||||||
|
refreshInstance()
|
||||||
|
return tryResumeInstanceOrCreate()
|
||||||
|
}
|
||||||
|
|
||||||
final override suspend fun awaitResumeInstance(): H = awaitResumeInstanceImpl(0)
|
final override suspend fun awaitResumeInstance(): H = awaitResumeInstanceImpl(0)
|
||||||
|
|
||||||
private tailrec suspend fun awaitResumeInstanceImpl(attempted: Int): H {
|
private tailrec suspend fun awaitResumeInstanceImpl(attempted: Int): H {
|
||||||
@ -73,13 +79,17 @@ internal abstract class AbstractKeepAliveNetworkHandlerSelector<H : NetworkHandl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
synchronized(this) { // avoid concurrent `createInstance()`
|
refreshInstance()
|
||||||
if (getResumedInstance() == null) this.current.compareAndSet(null, createInstance())
|
|
||||||
}
|
|
||||||
awaitResumeInstanceImpl(attempted) // directly retry, does not count for attempts.
|
awaitResumeInstanceImpl(attempted) // directly retry, does not count for attempts.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected open fun refreshInstance() {
|
||||||
|
synchronized(this) { // avoid concurrent `createInstance()`
|
||||||
|
if (getResumedInstance() == null) this.current.compareAndSet(null, createInstance())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
@JvmField
|
||||||
var DEFAULT_MAX_ATTEMPTS =
|
var DEFAULT_MAX_ATTEMPTS =
|
||||||
|
@ -23,6 +23,11 @@ internal interface NetworkHandlerSelector<H : NetworkHandler> {
|
|||||||
*/
|
*/
|
||||||
fun getResumedInstance(): H?
|
fun getResumedInstance(): H?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the currently alive [NetworkHandler] or creates a new one.
|
||||||
|
*/
|
||||||
|
fun tryResumeInstanceOrCreate(): H
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an alive [NetworkHandler], or suspends the coroutine until the connection has been made again.
|
* Returns an alive [NetworkHandler], or suspends the coroutine until the connection has been made again.
|
||||||
*
|
*
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
package net.mamoe.mirai.internal.network.handler.selector
|
package net.mamoe.mirai.internal.network.handler.selector
|
||||||
|
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.selects.SelectClause1
|
import kotlinx.coroutines.channels.ReceiveChannel
|
||||||
import net.mamoe.mirai.internal.network.handler.NetworkHandler
|
import net.mamoe.mirai.internal.network.handler.NetworkHandler
|
||||||
import net.mamoe.mirai.internal.network.handler.NetworkHandler.State
|
import net.mamoe.mirai.internal.network.handler.NetworkHandler.State
|
||||||
import net.mamoe.mirai.internal.network.handler.NetworkHandlerContext
|
import net.mamoe.mirai.internal.network.handler.NetworkHandlerContext
|
||||||
@ -44,10 +44,9 @@ internal class SelectorNetworkHandler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val state: State
|
override val state: State
|
||||||
get() = selector.getResumedInstance()?.state ?: State.INITIALIZED
|
get() = selector.tryResumeInstanceOrCreate().state
|
||||||
override val onStateChanged: SelectClause1<State>
|
override val stateChannel: ReceiveChannel<State>
|
||||||
get() = selector.getResumedInstance()?.onStateChanged
|
get() = selector.tryResumeInstanceOrCreate().stateChannel
|
||||||
?: scope.async { instance().state }.onAwait
|
|
||||||
|
|
||||||
override suspend fun resumeConnection() {
|
override suspend fun resumeConnection() {
|
||||||
instance() // the selector will resume connection for us.
|
instance() // the selector will resume connection for us.
|
||||||
|
@ -47,12 +47,16 @@ internal open class TestNetworkHandler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "TestState($correspondingState)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(TestOnly::class)
|
@OptIn(TestOnly::class)
|
||||||
fun setState(correspondingState: NetworkHandler.State) {
|
fun setState(correspondingState: NetworkHandler.State): TestState? {
|
||||||
// `null` means ignore checks. All test states have same type TestState.
|
// `null` means ignore checks. All test states have same type TestState.
|
||||||
setStateImpl(null) { TestState(correspondingState) }
|
return setStateImpl(null) { TestState(correspondingState) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private val initialState = TestState(NetworkHandler.State.INITIALIZED)
|
private val initialState = TestState(NetworkHandler.State.INITIALIZED)
|
||||||
|
Loading…
Reference in New Issue
Block a user