Do not resume state while it is already closed

This commit is contained in:
Him188 2021-04-21 12:49:19 +08:00
parent 0e1b9da5e4
commit d70475b8ba
2 changed files with 14 additions and 6 deletions

View File

@ -183,7 +183,7 @@ internal abstract class NetworkHandlerSupport(
* You may need to call [BaseStateImpl.resumeConnection] to activate the new state, as states are lazy.
*/
protected inline fun <S : BaseStateImpl> setState(crossinline new: () -> S): S = synchronized(this) {
// we can add hooks here for debug.
if (_state.correspondingState == NetworkHandler.State.CLOSED) error("Cannot change state while it has already been CLOSED.")
val stateObserver = context.getOrNull(StateObserver)

View File

@ -118,7 +118,8 @@ internal class NettyNetworkHandler(
}
future.channel().closeFuture().addListener {
setState { StateConnectionLost(it.cause()) }
if (_state.correspondingState == State.CLOSED) return@addListener
setState { StateConnecting(ExceptionCollector(it.cause())) }
}
return contextResult.await()
@ -189,9 +190,15 @@ internal class NettyNetworkHandler(
*
* Dropped when state becomes [StateOK].
*/
private val collectiveExceptions: ExceptionCollector
private val collectiveExceptions: ExceptionCollector,
wait: Boolean = false
) : NettyState(State.CONNECTING) {
private val connection = async { createConnection(decodePipeline) }
private val connection = async {
if (wait) {
delay(5000)
}
createConnection(decodePipeline)
}
private val connectResult = async {
connection.join()
@ -199,8 +206,9 @@ internal class NettyNetworkHandler(
}.apply {
invokeOnCompletion { error ->
if (error != null) setState {
StateClosed(
CancellationException("Connection failure.", collectiveExceptions.collectGet(error))
StateConnecting(
collectiveExceptions.apply { collect(error) },
wait = true
)
} // logon failure closes the network handler.
// and this error will also be thrown by `StateConnecting.resumeConnection`