Skip to content

feat(serial): Step 3 读线程生命周期修复 - #10

Merged
Gyanano merged 1 commit into
developfrom
feature/serial-core-step3-lifecycle
Sep 2, 2026
Merged

feat(serial): Step 3 读线程生命周期修复#10
Gyanano merged 1 commit into
developfrom
feature/serial-core-step3-lifecycle

Conversation

@Gyanano

@Gyanano Gyanano commented Sep 2, 2026

Copy link
Copy Markdown
Owner

RFC #3 Step 3:读线程生命周期

跟踪 issue:#3(前置:#4#5#6

改动

后端

  • disconnect() 返回读线程 JoinHandle,bounded join(500ms,is_finished 轮询)移到 Tauri 命令层、大锁外执行,取代原锁内 200ms sleep;join 超时则 detach 不阻塞 UI
  • connect() 开头防御性 join 残留读线程 → close→reopen EBUSY 竞态根治
  • 读线程致命错误不再静默:错误写入共享状态 → 下次状态轮询(1s)is_connected=falseConnectionStatus 新增 connection_error 字段;惰性清理写句柄与录制
  • 读线程任何退出路径(shutdown / 致命错误)都会 FrameSegmenter::flush() 打捞残留分帧,尾部数据不再蒸发

前端

  • 状态轮询检测到「连接意外断开」转换时 toast 告警(中英 i18n),手动断开不打扰
  • 修复定时发送僵尸态:断开连接或清空内容时开关自动复位(原需手动关开才能恢复)

验证

  • cargo test 34/34 全绿,零警告;npm run build 通过
  • 测试调整:golden_reader_death_is_silent_today(钉住旧坏行为)→ reader_death_marks_connection_lost_and_salvages_pending(钉住新行为);新增 reconnect 竞态测试与 flush 单测
  • 有头应用人工硬件验证(FTDI 环回):
    • 拔线 → 1s 内离线 + toast + 定时开关自动复位 ✅
    • 拔线重插立即重连成功(原 EBUSY 竞态)✅
    • 快速断连/重连循环 ✅
    • 断开时数据完整保留 ✅
    • 收发/录制/导出回归 ✅

范围外


Note

Medium Risk
Changes core serial connection lifecycle (thread join timing, lazy disconnect on reader death, and reconnect races); mistakes could block polling or leave ports stuck, though bounded join and tests mitigate this.

Overview
Implements RFC #3 Step 3 so serial read-thread shutdown, fatal errors, and reconnect behave correctly instead of leaving a “connected” UI or dropping tail bytes.

Backend: disconnect() now returns the reader JoinHandle and does fast cleanup under the manager lock; bounded join (500ms) runs in the Tauri disconnect_port command after releasing the lock (replacing a lock-held 200ms sleep). connect() joins any stale reader before reopen to avoid EBUSY on quick replug. Fatal read errors are stored on the reader thread; get_status lazily marks the session disconnected, exposes new connection_error on ConnectionStatus, and tears down the port/recording. On any reader exit, FrameSegmenter::flush() emits buffered RX so partial frames are not lost.

Frontend: Status polling shows a one-time toast when transitioning from connected to disconnected with connection_error (manual disconnect has no error). SendPanel turns off scheduled sending when disconnected or the payload is cleared, fixing a “scheduled active” zombie state. EN/zh-CN strings added for connection loss.

Reviewed by Cursor Bugbot for commit 4cf035c. Bugbot is set up for automated code reviews on this repo. Configure here.

… salvage

RFC #3 Step 3:
- disconnect() returns the reader JoinHandle and the (bounded, 500ms) join
  now happens OUTSIDE the big manager lock in the Tauri command, replacing
  the in-lock 200ms sleep. connect() joins any stale reader defensively,
  fixing the close->reopen EBUSY race.
- Reader-thread death is no longer silent: the error is recorded, the next
  status poll (1s) flips is_connected=false with connection_error set, and
  the frontend toasts 'Connection lost: ...' once per transition.
  ConnectionStatus gains a connection_error field.
- Pending partial frames are flushed (salvaged) on ANY reader exit instead
  of vanishing; new FrameSegmenter::flush().
- Fix scheduled-send zombie state: on disconnect or emptied payload the
  SendPanel switch now resets instead of showing 'scheduled active' with a
  dead timer.

Tests: 34/34 green (golden_reader_death_is_silent_today replaced by
reader_death_marks_connection_lost_and_salvages_pending; new
disconnect_returns_joinable_handle_and_reconnect_is_immediate +
flush_drains_pending_regardless_of_idle). Hardware-verified: unplug
detection + toast + switch reset, replug reconnect, rapid
disconnect/reconnect cycles, recording/export regression.
@cursor

cursor Bot commented Sep 2, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_8937df3d-8a14-48a5-a8d2-87356143fe6f)

@Gyanano
Gyanano merged commit 3ed553b into develop Sep 2, 2026
3 checks passed
@Gyanano
Gyanano deleted the feature/serial-core-step3-lifecycle branch September 2, 2026 11:24
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