Repository navigation
feat(cli): add JSON Lines control channel for headless frontends - #363
TimmySheep wants to merge 1 commit into
Conversation
|
感谢这个 PR,方向我是认可的:给 但这个 PR 现在不能合:我在真实二进制上实测确认, 环境说明Linux x86_64 / rustc 1.99.0 / debug 构建。沙箱里没有真实声卡,只有 ALSA 的 🔴 阻塞:进程在任何退出路径上都不退出现象
实测结果(原版代码):
最后一条最需要你注意: 复现cd tauri-app && cargo build -p micyou-cli
# 1) stop 之后进程不退出(124 = 被 timeout 杀掉)
echo '{"v":1,"type":"command","id":"1","name":"stop","payload":{}}' \
| timeout 20 ./target/debug/micyou-cli serve --jsonl > /tmp/out.jsonl
echo "rc=$?"; cat /tmp/out.jsonl
ls ~/.local/share/micyou/mode.lock # 残留
# 2) 启动失败:stdout 一个字节都没有,进程也不退出
python3 -c "import socket,time;s=socket.socket();s.setsockopt(1,2,1);s.bind(('0.0.0.0',8554));s.listen(1);time.sleep(30)" &
timeout 20 ./target/debug/micyou-cli serve --jsonl; echo "rc=$?"根因比"漏了一个 drop"更深,请注意别只改 drop 顺序我试过在
而 所以问题的本质是:"靠 channel 断开来让写线程退出"这个前提不成立,CLI 无法保证所有 需要你改的方向不要把写线程的退出条件寄托在 sender 全部 drop 上。请给它一个不依赖引用计数的显式关闭途径,并且 另外强烈建议补一个端到端回归测试:启动 🟠 一行坏输入就会拆掉整个音频服务
let line = line_result.map_err(|error| format!("invalid JSONL input: {error}"))?;
这和同一个循环里 JSON 解析错误的处理是矛盾的: 而且不可恢复:stdin 线程在 对一个面向"第三方前端与自动化脚本"的接口,一个字节错误就打死麦克风服务,健壮性不够;AGENTS.md 的约定也是 "validate at trust boundaries … prefer bounded limits and quarantine over panics"。 # 复现:服务被一行超长输入拆掉
python3 -c "print('{\"v\":1,'+' '*70000+'}')" \
| timeout 20 ./target/debug/micyou-cli serve --jsonl请把它降级成协议错误:发错误帧、丢弃到下一个 🟠 阻塞式 send 出现在 async 上下文和音频/网络线程里
失败链条:前端停止读 stdout → OS 管道缓冲(约 64 KiB)写满 → 写线程卡在 实测:完全不读 stdout + 灌 900 条 # 复现
import json, subprocess, time, signal, os
p = subprocess.Popen(["./target/debug/micyou-cli","serve","--jsonl"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, # 故意不读 stdout
stderr=subprocess.DEVNULL, text=True, bufsize=1)
time.sleep(3)
for i in range(900):
p.stdin.write(json.dumps({"v":1,"type":"command","id":f"m{i}","name":"setMuted",
"payload":{"isMuted":i%2==0}})+"\n")
p.stdin.flush(); time.sleep(3)
p.send_signal(signal.SIGINT); print(p.wait(timeout=15)) # 超时遥测走 顺带提醒一个坑: 🟠 其他需要处理的问题1. 关键事件可能乱序。 2. select 循环里执行同步阻塞操作。 3. 没有处理 SIGTERM。 AGENTS.md 里写的就是 CLI"适合终端、systemd 和脚本",你 PR 描述里的目标用户也是无头前端和自动化脚本,但 🟡 合并前需要补的错误码语义失真。 许可证头不合规。 协议完全没有文档。 这是一个带版本号、要给第三方长期依赖的对外契约,但 缺初始状态快照。 前端在
还有一点请在文档里写明: ⚪ 细节
关于验证你自述的构建/clippy/测试结果我复核过,都是真的;PR 描述里也诚实标注了"Windows 构建及真实设备音频端到端尚未验证",这点很好。但恰恰漏掉了唯一最重要的那条手工验证:实际跑一次 麻烦修完后按这个清单再验一遍:
有问题随时在这条 PR 下讨论。整体设计和代码质量我是满意的,主要卡点集中在生命周期和背压这两块,改完就可以推进了。 |
背景
micyou-cli serve目前只输出面向终端的人类可读日志,缺少供第三方前端与自动化脚本使用的运行时控制接口。变更
serve --jsonl;默认 CLI 行为与现有文本输出保持不变。本地验证
cargo test --locked -p micyou-cli:3 项通过。cargo build --locked -p micyou-cli与cargo build --locked -p micyou-cli --release:通过。cargo clippy --locked --workspace --all-targets:通过。bun install --frozen-lockfile与bun run build:通过。./gradlew :composeApp:assembleDebug:通过(JDK 21、项目 Gradle 9.8 wrapper、Android API 37)。cargo test --locked -- --test-threads=1:137/141 通过。1 个文件名大小写查找测试和 3 个 UDP 测试(WouldBlock)在未打补丁的固定基线也复现,未归因于此改动。Windows 构建及真实设备音频端到端尚未验证;请以 CI 结果补充跨平台验收。