Repository navigation
fix(swift): 会话结束时 Swift 运行时偶尔不退出,测试加超时保护(#387) - #499
Merged
Merged
Conversation
macOS 上,在非主线程阻塞的 read() 偶尔不被对端的 shutdown 唤醒:宿主关闭会话后 Swift 运行时一直等下去,宿主等它退出,CI 卡到超时(swift_rows_follow_the_row_contract、rutis-host 的 Swift 测试)。LineChannel 改为先 poll(被唤醒;超时 1 秒也再看一次)再 read。swift_runtime.rs 与 rutis-host tests/swift.rs 的启动、调用、退出、停止都加上超时保护,回归时快速失败。
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.
Swift 测试在自托管 Mac 上偶发卡住(
network-macos里swift_rows_follow_the_row_contract卡 1 小时 40 分;Kotlin PR #498 的runtimes-swift里 rutis-host 的 Swift 测试卡到作业超时)的根因修复与超时保护。#387 的一部分,单独提出以尽快合入。根因
宿主(rutis-bridge 的
Process)结束会话时对 socket 做shutdown(Both),等运行时退出。Swift 运行时在专用的会话线程上阻塞于read(fd)。macOS 上,在非主线程阻塞的read()偶尔不被对端的shutdown唤醒:运行时一直等,宿主一直等它退出。复现与确认(本机,macOS 26.6):
swift_runtime测试二进制循环运行(2 个测试线程),每次 6–120 轮内卡住一次;卡住时运行时进程的会话线程在LineChannel.receive→read,主线程在等会话结束,宿主侧已shutdown成功(getsockopt(LOCAL_PEERPID)确认就是这个进程的 socket)、读线程已读到 EOF 并等进程退出。read,父进程shutdown(SHUT_RDWR),约 6000 次中 6 次子进程不醒;把read换成先poll(POLLIN)再read,6000 次 0 次。Go、Python、Node、Bun 的运行时都用事件循环(kqueue)等 socket,不受影响。修复
LineChannel.receive:先poll(POLLIN, 1 s),就绪才read;超时也再看一次,即使唤醒丢了,最迟 1 秒后看到 EOF。swift_runtime.rs的运行时启动(两倍 HANG_GUARD)、退出(dispose)、ctx.shutdown、旧宿主用例的accept;rutis-hosttests/swift.rs的宿主启动、装载、每次调用、最后的shut_down。回归时在几十秒内失败并说明卡在哪一步,而不是占住 runner。验证
swift_runtime循环 300 轮 + 150 轮,0 次卡住(修复前同样的循环 4 次都在 120 轮内卡住)。RutisSelfTest32、swift_runtime、runtime_conformance/session_matrix/value_roundtrip的 Swift 列、swift_rows、multilang_swift、rutis-host--test swift全过。(也排查了“同一 .build 里并发 swift build”:各 runner 实例有各自的检出目录,同一测试进程内的并发构建由 SwiftPM 的锁串行,不是这次的原因。)