Replies: 2 comments
|
This report matches the current tool-lifecycle contract and is broader than a performance concern. In rc.8, The migration should preserve more than stdout:
For helpers that spawn descendants, the DSH subprocess seam is the stronger owner because its termination and wait contracts are tree-scoped. I published a complete migration example and acceptance matrix here: The source contract is |
|
Excellent report — the checkpoint-context detail is the crux, and it's worth making the mechanism explicit because it's why this failure is a hard freeze rather than a mere slowdown. Why checkpoint-context spawnSync is uniquely deadly. The freeze stack you captured is the exact signature: fs-close completion ( This is the extreme end of a "tool work is not preemptable by the harness" family. The contract at Two concrete zero-code additions that complement the doc fix:
The 6-plugin migration pattern you validated (spawnSync → promisify(execFile) + timeout + exit-status preservation) is the right plugin-side answer; the framework-side ask is: (a) add the explicit "no synchronous blocking in execute" prohibition to the tool-authoring guide with the checkpoint mechanism explained, (b) document |
Uh oh!
There was an error while loading. Please reload this page.
环境:macOS / node v22.23.1 / dsh 0.1.0-rc.7
摘要:工具插件在
async execute()内同步调用spawnSync,当该回调被工具调度在 microtask checkpoint 中执行时(由会话写盘 fs close 完成回调触发 checkpoint),spawnSync 内部嵌套运行事件循环(uv_run),与未完成的 checkpoint 重入 → 事件循环永久冻结(HTTP 000,仅 kill -9 恢复)。生产实例一周内挂死 3 次。挂死栈(macOS sample,5s 采样 4233 次全同):
触发链:活跃会话周期写盘(
writeAtomic→ FileHandle close,dsh-session-projection-cachewrite-behind 每 5s)→ 完成回调触发 microtask checkpoint → checkpoint 中排队的工具调度 await 续体执行 →spawnSync→ 嵌套uv_run死锁。libuv 4 工作线程全空闲(非线程池饥饿)。对照实验(逐一否定候选假说):
必要条件 = spawnSync 在 checkpoint 中执行;大会话读取等只是概率放大器。
影响面:任何第三方插件作者都可能写出
async execute() { spawnSync(...) }(最自然的写法)——defineTool契约未禁止/警告此用法,属框架文档/契约缺口。建议:
@deepseek-ai/dsh-tools文档明示execute内禁止同步阻塞(spawnSync/execSync/execFileSync 等)spawnSync→promisify(execFile),超时/非 0 退出在 catch 提取 stdout/stderr,status 语义保持All reactions