fix: Enhance connection robustness by rebuilding NWConnection on failure - #71
Open
RainYangty wants to merge 1 commit into
Open
fix: Enhance connection robustness by rebuilding NWConnection on failure#71RainYangty wants to merge 1 commit into
RainYangty wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This Pull Request refactors the
MaaToolClientinitialization logic to significantly improve its resilience when establishing a network connection.The original implementation attempted to handle the
.failedconnection state primarily by callingconnection.restart(). While this works for the.waitingstate, a hard.failedstate inNWConnectionoften requires a more thorough reset.The fix introduces an outer
whileloop around the connection setup. Now, when a connection enters the.failedstate, the client explicitly callsconnection.cancel()on the faulty instance, breaks out of the state-watching loop, and allows the outerwhileloop to create a completely newNWConnectionfor the next retry attempt.This ensures a cleaner and more reliable retry mechanism, as it avoids depending on the internal state recovery of the previously failed connection object. The core functionality and connection properties remain the same.
Reason for Change
In networking, especially when dealing with explicit connection failures (e.g., connection refused, network down), simply calling
restart()on an existing connection object that is in a.failedstate may not always succeed, as the underlying resources might not be cleanly released.The revised logic offers a more definitive reset for failed connection attempts:
.failedconnection.restart()(Potentially unreliable)..failedconnection.cancel()NWConnection(More reliable, full reset).Additionally, the PR includes minor refactoring to enhance concurrency safety within the
actor:connectionproperty is changed fromlettovarto allow for re-assignment within the initializer's retry loop.cancelActorConnection()is introduced to safely performconnection.cancel()within the actor's isolated context, particularly when theAsyncStreamis terminated.Key Changes
private let connection: NWConnectiontoprivate var connection: NWConnection.whileloop..failedState: In the state machine,case .failednow explicitly callsconnection.cancel()and uses a labeledbreak(break state_enum) to exit the innerfor await stateloop, initiating the creation of a new connection by the outerwhileloop.private func cancelActorConnection()and updated theAsyncStream.onTerminationhandler to call this method, ensuringconnection.cancel()is performed safely on the actor.Files Affected
MaaToolClient.swift摘要
本次拉取请求(PR)重构了
MaaToolClient的初始化逻辑,以显著提高其在建立网络连接时的健壮性。原始实现主要通过调用
connection.restart()来处理连接失败的.failed状态。虽然这对.waiting状态是有效的,但对于硬性的.failed状态,NWConnection通常需要更彻底的重置。此修复在连接设置的外部引入了一个
while循环。现在,当连接进入.failed状态时,客户端会显式地对失败的实例调用connection.cancel(),跳出状态监听循环,并允许外部while循环在下一次重试时创建一个全新的NWConnection实例。这确保了更清晰、更可靠的重试机制,因为它避免了依赖先前失败连接对象的内部状态恢复。核心功能和连接属性保持不变。
更改原因
在网络编程中,特别是在遇到明确的连接失败(例如:连接被拒绝、网络中断)时,简单地对处于
.failed状态的现有连接对象调用restart()可能无法总是成功,因为底层资源可能没有被彻底释放。修改后的逻辑为失败的连接尝试提供了更明确的重置:
.failedconnection.restart()(可能不可靠)。.failedconnection.cancel()NWConnection(更可靠,完全重置)。此外,此 PR 还包含细微的重构,以增强
actor内的并发安全性:connection属性从let更改为var,以便在初始化程序的重试循环中能够重新赋值。cancelActorConnection(),用于安全地在 Actor 的隔离上下文中执行connection.cancel(),特别是在AsyncStream终止时。主要更改
private let connection: NWConnection更改为private var connection: NWConnection。while循环包裹连接创建和状态监控逻辑。.failed状态: 在状态机中,case .failed现在显式调用connection.cancel(),并使用带标签的break(break state_enum) 跳出内部for await state循环,由外部while循环来启动新连接的创建。private func cancelActorConnection(),并更新AsyncStream.onTermination处理器以调用此方法,确保connection.cancel()在 Actor 上安全执行。受影响的文件
MaaToolClient.swift