mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-31 11:50:09 +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 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* 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
|
package net.mamoe.mirai.internal.network.handler
|
||||||
@ -159,6 +159,26 @@ internal abstract class NetworkHandlerSupport(
|
|||||||
final override val coroutineContext: CoroutineContext =
|
final override val coroutineContext: CoroutineContext =
|
||||||
this@NetworkHandlerSupport.coroutineContext + Job(this@NetworkHandlerSupport.coroutineContext.job)
|
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
|
open fun getCause(): Throwable? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -248,7 +268,7 @@ internal abstract class NetworkHandlerSupport(
|
|||||||
val stateObserver = context.getOrNull(StateObserver)
|
val stateObserver = context.getOrNull(StateObserver)
|
||||||
|
|
||||||
val impl = try {
|
val impl = try {
|
||||||
new() // inline only once
|
new()
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
stateObserver?.exceptionOnCreatingNewState(this, old, e)
|
stateObserver?.exceptionOnCreatingNewState(this, old, e)
|
||||||
throw e
|
throw e
|
||||||
@ -257,8 +277,14 @@ internal abstract class NetworkHandlerSupport(
|
|||||||
check(old !== impl) { "Old and new states cannot be the same." }
|
check(old !== impl) { "Old and new states cannot be the same." }
|
||||||
|
|
||||||
stateObserver?.beforeStateChanged(this, old, impl)
|
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
|
_state = impl // update current state
|
||||||
old.cancel(StateSwitchingException(old, impl)) // close old
|
old.cancel(StateSwitchingException(old, impl)) // close old
|
||||||
|
impl.afterUpdated() // now do post-update things.
|
||||||
|
|
||||||
stateObserver?.stateChanged(this, old, impl) // notify observer
|
stateObserver?.stateChanged(this, old, impl) // notify observer
|
||||||
_stateChannel.trySend(impl.correspondingState) // notify selector
|
_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 许可证的约束, 可以在以下链接找到该许可证.
|
* 此源代码的使用受 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.
|
* 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
|
package net.mamoe.mirai.internal.network.handler.state
|
||||||
@ -22,7 +22,7 @@ import net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport
|
|||||||
internal interface StateObserver {
|
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(
|
fun beforeStateChanged(
|
||||||
networkHandler: NetworkHandlerSupport,
|
networkHandler: NetworkHandlerSupport,
|
||||||
|
@ -259,14 +259,16 @@ internal open class NettyNetworkHandler(
|
|||||||
*/
|
*/
|
||||||
private val collectiveExceptions: ExceptionCollector,
|
private val collectiveExceptions: ExceptionCollector,
|
||||||
) : NettyState(State.CONNECTING) {
|
) : NettyState(State.CONNECTING) {
|
||||||
private val connection = async {
|
private lateinit var connection: Deferred<io.netty.channel.Channel>
|
||||||
createConnection()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("JoinDeclarationAndAssignment")
|
@Suppress("JoinDeclarationAndAssignment")
|
||||||
private val connectResult: Deferred<Unit>
|
private lateinit var connectResult: Deferred<Unit>
|
||||||
|
|
||||||
|
override fun startState() {
|
||||||
|
connection = async {
|
||||||
|
createConnection()
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
|
||||||
connectResult = async {
|
connectResult = async {
|
||||||
connection.join()
|
connection.join()
|
||||||
context[SsoProcessor].login(this@NettyNetworkHandler)
|
context[SsoProcessor].login(this@NettyNetworkHandler)
|
||||||
@ -318,7 +320,8 @@ internal open class NettyNetworkHandler(
|
|||||||
protected inner class StateLoading(
|
protected inner class StateLoading(
|
||||||
private val connection: NettyChannel,
|
private val connection: NettyChannel,
|
||||||
) : NettyState(State.LOADING) {
|
) : NettyState(State.LOADING) {
|
||||||
init {
|
|
||||||
|
override fun startState() {
|
||||||
coroutineContext.job.invokeOnCompletion {
|
coroutineContext.job.invokeOnCompletion {
|
||||||
if (it != null) {
|
if (it != null) {
|
||||||
connection.close()
|
connection.close()
|
||||||
@ -351,7 +354,7 @@ internal open class NettyNetworkHandler(
|
|||||||
private val connection: NettyChannel,
|
private val connection: NettyChannel,
|
||||||
private val configPush: Job,
|
private val configPush: Job,
|
||||||
) : NettyState(State.OK) {
|
) : NettyState(State.OK) {
|
||||||
init {
|
override fun startState() {
|
||||||
coroutineContext.job.invokeOnCompletion { err ->
|
coroutineContext.job.invokeOnCompletion { err ->
|
||||||
if (err is StateSwitchingException) {
|
if (err is StateSwitchingException) {
|
||||||
if (err.new.correspondingState == State.CLOSED) {
|
if (err.new.correspondingState == State.CLOSED) {
|
||||||
@ -396,7 +399,8 @@ internal open class NettyNetworkHandler(
|
|||||||
protected inner class StateClosed(
|
protected inner class StateClosed(
|
||||||
val exception: Throwable?,
|
val exception: Throwable?,
|
||||||
) : NettyState(State.CLOSED) {
|
) : NettyState(State.CLOSED) {
|
||||||
init {
|
|
||||||
|
override fun afterUpdated() {
|
||||||
close(exception)
|
close(exception)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user