perf: 桥变化才写、stdin 优先、stream 50ms 轮询

1. 桥写放大:旧代码每 ~50ms 轮询都无条件重写 state 和帧
   文件(约 40 次原子 temp+replace/s 走 runsc gofer,
   泵持久返回同一帧、updated_at 每轮都变,字节其实不变)。
   现帧字节不变不写;state 只在 url/title/started/holder/
   streaming 变化时写,或 0.5s 心跳一次(判死阈值 30s,
   绰绰有余);静态页写量从 ~40次/s 降到 ~2次/s。
2. MCP 主循环 stdin 优先:旧循环先 drain 再读 stdin,
   每次工具调用都先付一轮文件 IO。现 pending 请求先处理,
   空闲轮询 drain,忙时 200ms 保底 drain 一次防饿死。
3. stream 轮询 200ms → 50ms,画面延迟下限随之下降。
附回归测试:无变化轮询不重写、帧变化立即写、holder
变化绕过节流立即写。
This commit is contained in:
host committed 2026-10-30 13:36:24 +08:00
1 parent e9370d7291
commit 910168126d
4 files changed
+93 -21

No files matched your search

+2 -2
View File
@@ -5318,7 +5318,7 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
def _browser_stream(self, user_id, task_id):
"""GET /tasks/{id}/browser/stream: SSE from bridge files.
Polls the frame file every 200ms and emits a data line
Polls the frame file every 50ms and emits a data line
whenever its bytes change (plus a heartbeat with the
current holder at least every 5s). Ends the stream when
the state file goes stale, so a dead session reads as a
@@ -5364,7 +5364,7 @@ class CloudControlPlaneHandler(BaseHTTPRequestHandler):
self.wfile.write(
("data: %s\n\n" % payload).encode("utf-8"))
self.wfile.flush()
time.sleep(0.2)
time.sleep(0.05)
except (BrokenPipeError, ConnectionResetError, OSError):
pass