Skip to content

fix(swift): 会话结束时 Swift 运行时偶尔不退出,测试加超时保护(#387) - #499

Merged
eric8810 merged 1 commit into
mainfrom
fix/swift-channel-eof
Oct 19, 2026
Merged

eric8810 merged 1 commit into
mainfrom
fix/swift-channel-eof

Conversation

@eric8810

Copy link
Copy Markdown
Contributor

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 并等进程退出。
  • 与 Swift、rutis 无关的 C 程序同样复现:子进程在第二个线程上阻塞 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-host tests/swift.rs 的宿主启动、装载、每次调用、最后的 shut_down。回归时在几十秒内失败并说明卡在哪一步,而不是占住 runner。

验证

  • 修复后 swift_runtime 循环 300 轮 + 150 轮,0 次卡住(修复前同样的循环 4 次都在 120 轮内卡住)。
  • RutisSelfTest 32、swift_runtime、runtime_conformance / session_matrix / value_roundtrip 的 Swift 列、swift_rows、multilang_swift、rutis-host --test swift 全过。

(也排查了“同一 .build 里并发 swift build”:各 runner 实例有各自的检出目录,同一测试进程内的并发构建由 SwiftPM 的锁串行,不是这次的原因。)

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 的启动、调用、退出、停止都加上超时保护,回归时快速失败。
@eric8810 eric8810 added this to the 0.14 milestone Oct 19, 2026
@eric8810
eric8810 merged commit 38a8657 into main Oct 19, 2026
26 checks passed
@eric8810 eric8810 modified the milestones: 0.14, 0.15 Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant