Skip to content

feat(serial): Step 4 事件推送替代轮询(RFC #3 收官) - #11

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

feat(serial): Step 4 事件推送替代轮询(RFC #3 收官)#11
Gyanano merged 1 commit into
developfrom
feature/serial-core-step4-events

Conversation

@Gyanano

@Gyanano Gyanano commented Sep 2, 2026

Copy link
Copy Markdown
Owner

RFC #3 Step 4:FrameBus + Nagle 合批 + serial://frames 桥接(收官步)

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

后端

  • bus.rs 新增Frame {session, seq, dir, t_mono_ns, t_wall, Arc<[u8]>}——seq 会话内从 1 严格递增、TX/RX 同序列;FrameBus 有界订阅队列(满则 drop-oldest + dropped_before 前缀缺口计数,读线程零阻塞);Nagle 合批(GUI_DEFAULT 16ms/64KiB/512 帧/4096 队列;空闲消费者单帧 ≥4ms 间隔即推)
  • 读循环与 send_data写缓冲之后 publish(双写存续期:日志缓冲/录制/统计不动,全部 golden 测试原样通过)
  • get_logs_snapshot {epoch, session, entries} 初始对齐;clear_logs 返回递增 epoch 防快照复活

桥接(main.rs)

应用级 pump 线程:有界阻塞 recv → 显示装饰(display_text/时间戳)→ emit("serial://frames");热路径 DTO 不携带原始字节(seq/dir/len + 装饰文本,JSON 体积大幅下降)

前端

  • useSerialLogs:快照对齐 → 增量 append(rAF 节流);seq 去重;session 变更自动重对齐;epoch 不匹配的快照直接丢弃(清空永不复活);dropped_before>0 插入「丢失 N 帧」占位行;trim 镜像后端 1000 上限;LogViewer 行键改 session-seq
  • 回滚开关:localStorage serialEventPush=0 恢复 100ms 轮询

验证

  • cargo test 40/40(bus 5 个单测:seq 单调/会话重置/单帧即推/合批/drop-oldest 缺口对账;harness 集成测试:真实读线程 TX+RX seq 连续无丢无重)
  • 有头应用 + FTDI 环回人工验证:收发即时性、狂发计数无丢无重、清空不复活、搜索/滚底/计数器、拔线检测全部通过

后续解锁


Note

Medium Risk
Changes the serial read/send hot path, background pump thread, and frontend log state machine; rollback polling exists but default behavior is new event synchronization logic.

Overview
Replaces the default 100ms full-clone get_logs polling with an event-driven log path: initial get_logs_snapshot alignment plus incremental serial://frames batches from a backend pump thread.

Backend adds a FrameBus (bus.rs) with per-session seq (TX/RX share one sequence), bounded subscriber queues (drop-oldest + dropped_before), and Nagle-style batching. RX and TX still write the in-memory log buffer first, then publish to the bus. clear_logs now returns a monotonic epoch; snapshots carry epoch/session so clears cannot resurrect stale rows. New command get_logs_snapshot.

Frontend useSerialLogs listens for batches, dedupes by seq, resyncs on session change, rAF-throttles appends, shows overload placeholders when dropped_before > 0, and mirrors the ~1000 entry cap. localStorage serialEventPush=0 restores polling. LogViewer row keys use session-seq / gap_key.

Existing get_logs remains for rollback/export alignment during the dual-write period.

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

Backend:
- New bus.rs: Frame {session, seq, dir, t_mono_ns, t_wall, Arc data} with
  per-session seq from 1 shared by TX/RX; FrameBus with bounded
  per-subscriber queues (drop-oldest + dropped_before prefix-gap
  accounting) and Nagle batching (GUI_DEFAULT 16ms/64KiB/512 frames/4096
  queue; lone frame for an idle consumer pushes immediately past a 4ms
  anti-storm interval).
- Read loop and send_data publish frames after the buffer write
  (dual-write coexistence: log buffer/text+raw recording/stats unchanged,
  all golden tests intact).
- New get_logs_snapshot command {epoch, session, entries}; clear_logs
  returns a bumped epoch.

Bridge (main.rs): app-lifetime pump thread consumes batches with bounded
blocking recv, decorates (display_text/timestamp) and emits
serial://frames; the wire DTO carries no raw bytes (seq/dir/len +
display text).

Frontend:
- useSerialLogs hook: snapshot alignment, incremental append with rAF
  throttling, seq dedupe, session-change resync, epoch guard so a snapshot
  racing a clear never resurrects entries, dropped_before placeholder rows,
  trim mirroring the backend 1000-entry cap; LogViewer keys rows by
  session-seq.
- Rollback switch: localStorage serialEventPush=0 restores the legacy
  100ms polling loop.

Tests: 40/40 green (5 new bus unit tests incl. drop-oldest prefix-gap
accounting; harness test asserting contiguous seq across RX/TX through
the real reader thread). Hardware-verified on FTDI loopback: burst
sending, clear-during-stream, search/autoscroll/counters, unplug.
@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_4ea154d0-3877-4840-ba49-8f6d3a04a982)

@Gyanano
Gyanano merged commit 8b365cc into develop Sep 2, 2026
3 checks passed
@Gyanano
Gyanano deleted the feature/serial-core-step4-events branch September 2, 2026 12:45
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