Skip to content

fix(ostool-server): isolate physical serial receive from the network executor - #186

Open
ZR233 wants to merge 1 commit into
mainfrom
codex/serial-reader-thread
Open

fix(ostool-server): isolate physical serial receive from the network executor#186
ZR233 wants to merge 1 commit into
mainfrom
codex/serial-reader-thread

Conversation

@ZR233

@ZR233 ZR233 commented Sep 11, 2026

Copy link
Copy Markdown
Member

问题

#185 把串口和 WebSocket 收发拆成四个异步 future,但物理串口仍依赖 HTTP/Tokio executor。管理状态投影中的同步设备枚举以及 ss / systemctl 等同步调用会占用 worker;当 executor 无法及时推进时,四个 future 的拆分不能保证物理 RX 继续排空。

TGOSKits 板卡 CIexec-cache 中出现 NUL、输出截断及超时。现场现象是调查线索,尚不能单凭该日志证明每次截断都由 executor 阻塞引起。本 PR 修复的是已经通过真实 PTY 确定性复现的接收进展缺口。

修改

  • Unix 物理 RX 由独立线程持续读取,使用 256 KiB 有界字节缓冲向异步会话传递数据;锁只保护内存复制,锁内不执行串口或网络 I/O。先登记 waker 再检查状态,避免丢失通知。
  • 异步 TX 与 WebSocket 继续沿用已有传输协议。QEMU 和非 Unix 后端保持原实现。没有修改 CI、波特率、成功匹配或测试超时。
  • 缓冲容量按字节约束,避免大量小读提前耗尽固定数量的消息槽。超限先保留已接收字节,再返回明确错误,不静默过滤或丢弃字节。
  • 关闭或取消时先通知并 join 接收线程,再释放串口/租约。接收线程不等待网络和缓冲容量,唯一阻塞点是 20 ms 串口读取;普通输出排空仍使用既有的一秒有界清理。

验证

  • 真实 PTY 红绿:阻塞唯一 Tokio worker,板端写入超过 PTY 内核缓冲容量的数据。旧实现稳定在 0.20 秒因写入超时失败;修复后同一用例完成并逐字节核对 64 KiB 数据。
  • 真实 PTY 验证缓冲溢出错误、取消后旧 reader 已退出且不消费下一所有者的数据。
  • cargo test -p ostool-server:146 项单元测试及 3 项会话集成测试全部通过。
  • cargo fmt --all -- --checkcargo clippy -p ostool-server --all-features、release 构建、差异检查通过。
  • 额外的 --all-targets -- -D warnings 检查遇到主线 api/router.rs 已有的 items_after_test_module 告警;未混入无关文件布局调整。

已部署到共享服务器 10.3.10.194,运行二进制 SHA256 为 d195b293016a460bb9e2a9b88b1c1698f2304c3c77d65dfc3b91bc01e45c110d。部署前确认租约已释放,保留原二进制备份。

部署后通过原始 cargo xtask starry test board --board orangepi-5-plus:exec-cache(2 号板)、NPU(3 号板)、网络(1 号板)3/3 全部通过,全组日志 0 NUL;各自监测区间的 overrun/frame/parity/buf_overrun 无新增。

提交 93bc1b0push CIPR CI 均已 completed/success。

此前 TGOSKits CI 的另一次 U-Boot DHCP 超时发生在内核入口之前,尚未建立与接收线程缺口的因果关系;重跑和部署后网络用例均通过,不将该单次现象当作本 PR 已定位的根因。

@mai-team-app mai-team-app Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

结论

请求修改。PR 的整体方向正确,但当前溢出路径仍可能丢失已经接收的串口字节。

变更概述

本 PR 在 Unix 上为物理串口 RX 增加独立线程和 256 KiB 有界字节缓冲,避免 Tokio/HTTP executor 暂停时停止排空串口;TX、WebSocket worker、QEMU 和非 Unix 后端基本保持原有结构。这个改动直接影响物理串口会话的错误传播、关闭清理和输出可靠性。

阻塞问题

  • ostool-server/src/serial/physical.rs:84(错误状态发布)与 ostool-server/src/serial/transport.rs:140-151(传输 tokio::select!)之间存在端到端契约缺口。物理 reader 会先保留缓冲字节,再让 AsyncRead 返回溢出错误;但 transport::run 一旦 serial read future 返回错误就立即结束 select,随即丢弃 WebSocket writer 和 output_rx 中已经排队的 chunks。处于 WebSocket 背压时,这会丢掉物理缓冲和传输队列中已经接收的数据,而不是按本 PR README 所述“在已缓冲字节之后报告溢出”。请在传播该错误前排空已接受的输出,或明确调整端到端契约并增加从 PhysicalSerial 经过 transport 到 WebSocket 的回归测试。

验证与审查上下文

  • 目标 head 93bc1b0f9012cb2eb15764dbfadfa4420dc52b0f 已确认;GitHub 上该 head 的两个 check (stable, x86_64-unknown-linux-gnu) 检查均为 completed/success,未发现由本 PR 导致的 CI 失败。
  • 本地工作区没有安装 cargo/rustc,因此 cargo fmt --check 无法启动,clippy 和 crate 测试也无法在本地运行;这属于审查环境限制。PR 描述中的 PTY 验证和 GitHub CI 结果已作为补充证据,但未覆盖上述 WebSocket 溢出路径。
  • PR 当前没有既有 review、inline comment 或 issue comment;因此没有未处理的历史审查意见。
  • 已检查相似变更:已合并的 PR #185 建立了有界串口/WebSocket worker 及清理语义,PR #186 是其物理 RX 隔离补充;未发现另一个活动中的重复 PR。除上述溢出后的输出保留问题外,QEMU、非 Unix 后端和 TX 路径看起来是隔离的。

Powered by gpt-5.6-luna

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