mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-05 23:50:08 +08:00
Network: change state initialization and update sequence:
- Do nothing in init block - Start state after notifying `beforeStateChanged` - StateClosed: do close after being updated to public close #1893
This commit is contained in:
parent
88e1146edc
commit
a5b52a0b7b
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal.network.handler
|
||||
@ -159,6 +159,26 @@ internal abstract class NetworkHandlerSupport(
|
||||
final override val coroutineContext: CoroutineContext =
|
||||
this@NetworkHandlerSupport.coroutineContext + Job(this@NetworkHandlerSupport.coroutineContext.job)
|
||||
|
||||
// Do not use init blocks to launch anything. Do use [startState]
|
||||
|
||||
/**
|
||||
* Starts things that should be done in this state.
|
||||
*
|
||||
* Called after this instance is initialized, and it is at suitable time for initialization.
|
||||
*
|
||||
* Note: must be fast.
|
||||
*/
|
||||
open fun startState() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after this instance is set to [_state]. (Visible publicly)
|
||||
*/
|
||||
open fun afterUpdated() {
|
||||
|
||||
}
|
||||
|
||||
open fun getCause(): Throwable? = null
|
||||
|
||||
/**
|
||||
@ -248,7 +268,7 @@ internal abstract class NetworkHandlerSupport(
|
||||
val stateObserver = context.getOrNull(StateObserver)
|
||||
|
||||
val impl = try {
|
||||
new() // inline only once
|
||||
new()
|
||||
} catch (e: Throwable) {
|
||||
stateObserver?.exceptionOnCreatingNewState(this, old, e)
|
||||
throw e
|
||||
@ -257,8 +277,14 @@ internal abstract class NetworkHandlerSupport(
|
||||
check(old !== impl) { "Old and new states cannot be the same." }
|
||||
|
||||
stateObserver?.beforeStateChanged(this, old, impl)
|
||||
|
||||
// We should startState before expose it publicly because State.resumeConnection may wait for some jobs that are launched in startState.
|
||||
// We cannot close old state before changing the 'public' _state to be the new one, otherwise every client will get some kind of exceptions (unspecified, maybe CancellationException).
|
||||
impl.startState() // launch jobs
|
||||
_state = impl // update current state
|
||||
old.cancel(StateSwitchingException(old, impl)) // close old
|
||||
impl.afterUpdated() // now do post-update things.
|
||||
|
||||
stateObserver?.stateChanged(this, old, impl) // notify observer
|
||||
_stateChannel.trySend(impl.correspondingState) // notify selector
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.internal.network.handler.state
|
||||
@ -22,7 +22,7 @@ import net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport
|
||||
internal interface StateObserver {
|
||||
|
||||
/**
|
||||
* Called when _state is being changed_, where [NetworkHandlerSupport._state] is still [previous].
|
||||
* Called when _state is being changed_, where [NetworkHandlerSupport._state] is still [previous], and new state is not yet started.
|
||||
*/
|
||||
fun beforeStateChanged(
|
||||
networkHandler: NetworkHandlerSupport,
|
||||
|
@ -259,14 +259,16 @@ internal open class NettyNetworkHandler(
|
||||
*/
|
||||
private val collectiveExceptions: ExceptionCollector,
|
||||
) : NettyState(State.CONNECTING) {
|
||||
private val connection = async {
|
||||
createConnection()
|
||||
}
|
||||
private lateinit var connection: Deferred<io.netty.channel.Channel>
|
||||
|
||||
@Suppress("JoinDeclarationAndAssignment")
|
||||
private val connectResult: Deferred<Unit>
|
||||
private lateinit var connectResult: Deferred<Unit>
|
||||
|
||||
override fun startState() {
|
||||
connection = async {
|
||||
createConnection()
|
||||
}
|
||||
|
||||
init {
|
||||
connectResult = async {
|
||||
connection.join()
|
||||
context[SsoProcessor].login(this@NettyNetworkHandler)
|
||||
@ -318,7 +320,8 @@ internal open class NettyNetworkHandler(
|
||||
protected inner class StateLoading(
|
||||
private val connection: NettyChannel,
|
||||
) : NettyState(State.LOADING) {
|
||||
init {
|
||||
|
||||
override fun startState() {
|
||||
coroutineContext.job.invokeOnCompletion {
|
||||
if (it != null) {
|
||||
connection.close()
|
||||
@ -351,7 +354,7 @@ internal open class NettyNetworkHandler(
|
||||
private val connection: NettyChannel,
|
||||
private val configPush: Job,
|
||||
) : NettyState(State.OK) {
|
||||
init {
|
||||
override fun startState() {
|
||||
coroutineContext.job.invokeOnCompletion { err ->
|
||||
if (err is StateSwitchingException) {
|
||||
if (err.new.correspondingState == State.CLOSED) {
|
||||
@ -396,7 +399,8 @@ internal open class NettyNetworkHandler(
|
||||
protected inner class StateClosed(
|
||||
val exception: Throwable?,
|
||||
) : NettyState(State.CLOSED) {
|
||||
init {
|
||||
|
||||
override fun afterUpdated() {
|
||||
close(exception)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user