v0.6.21
概要 / TL;DR
修复线上 team-server 在冷启动/高负载下反复卡死重启的问题,并把架构改成"重计算与前台隔离",在万级 skill / 十万级轨迹下也撑得住。
Fixes the team-server repeated freeze-and-restart under cold-start / heavy load, and re-architects heavy compute to run isolated from the web process — holds up at 10k+ skills / 60k+ trajectories.
⚠️ 升级后请盯一下第一波冷启动:探针不再超时、py-spy里不再有find_atom_entry_in_any_skill热栈即为正常。
根因 / Root cause
现象:health / watcher / web 三个探针同时 5s 超时,进程被反复重启。py-spy 定位:watcher 热循环 find_atom_entry_in_any_skill 对每个未打 clustered 标记的 atom 全量重读所有 skill 的 .candidates.yml(O(atoms×skills)),烧满一个核、握死 GIL,饿死跑异步探针的事件循环。embedding 后端其实很快,并非瓶颈。
py-spy showed the watcher hot loop re-reading every skill's .candidates.yml per un-clustered atom (O(atoms×skills)), pegging one core and starving the async event loop via the GIL. Embedding was not the bottleneck.
主要改动 / Highlights
- 热循环惰性缓存:每轮 sweep 惰性构建一次
atom_id→skill索引,仅在遇到未打标 atom 时才建;稳态全clustered零扫盘(1 万 skill 不再每轮白扫)。O(atoms×skills) → O(skills)。 - watcher / 画像拆为定时短命子进程:web 进程只留轻量调度线程 spawn 子进程,重计算全在独立解释器进程,GIL 与事件循环隔离;算完即退,不留常驻线程。
- 前端海量 skill 分页:
/api/v1/dashboard/skills加limit/offset分页 +name定向查,前端翻页,1 万 skill 不炸锅。 - 看板随主 app 挂载(主进程轻量后无需独立进程);观测端点
/watcher/status、/stats改读子进程落盘状态文件。 - 画像同步默认放慢到 600s(10 分钟);新增
server.sweep_timeout/profile_refresh_interval/profile_refresh_timeout配置。
升级 / Upgrade
pip install -U xskill # → 0.6.21
# 重启:xskill serve --server(自动挂看板 + 起 sweep/profile 内部调度器)测试 / Tests
全套 1573 单测通过。唯一未过的是 e2e test_canary_flip_promote_and_install_new_version —— 系环境问题(该 e2e 跑机器上已装的 0.6.16 二进制而非源码,而环境 websockets 16 移除了 WebSocketServerProtocol 打挂了 0.6.16),与本次改动无关。