Appearance
ACP client 未归还连接池导致每次发送冷启动,acp.runtime.ttlMinutes 配置失效
问题
使用 claude-agent-acp 或 gemini --acp adapter 时,即使配置了 acp.runtime.ttlMinutes,每次 agent 发送消息仍然都要经历冷启动(重新初始化 ACP 进程),导致响应极慢。
版本:openclaw 2026.4.15(npm global install)
根本原因分析(社区深度排查):
经代码审计发现三个死亡点必须同时修复:
runTurn缺少 finally 块:ACP client 执行完后未归还连接池,导致连接泄漏createInitialRecord不存储 mode 字段(L3909):初始化时丢失 mode 信息ensureSession的 reuse 分支不回填 mode(L3959):复用已有 session 时 mode 永远是 undefined
三个问题共同导致:每次 runTurn 都认为需要新建 session,即使连接池里有可用 client 也无法复用。
解决方案
方案一:等待官方修复
该问题已报告并提交了修复方案,关注官方 release notes。
方案二:临时降低冷启动影响
在 agents.defaults 中适当增大超时配置,减少因冷启动导致的请求失败:
yaml
agents:
defaults:
acp:
runtime:
ttlMinutes: 30 # 即使无法复用,也减少启动频率
startupTimeoutMs: 15000 # 给冷启动更多时间方案三:本地 patch(高级用户)
在 runTurn 的核心执行逻辑中添加 finally 块:
js
// 伪代码示意,具体路径需根据安装版本确认
async function runTurn(session, input) {
const client = await pool.acquire(session.acpxRecordId);
try {
return await client.turn(input);
} finally {
pool.release(client); // 确保归还
}
}同时在 createInitialRecord 返回值中补充 mode 字段,并在 ensureSession 的复用分支中回填。
常见问题
Q: 如何判断是否命中此 bug?
A: 查看 gateway 日志,若每次消息处理都出现 ACP cold start 或 initializing adapter 日志,而不是 reusing session,则说明连接池复用失败,属于此 bug 范围。
Q: acp.runtime.ttlMinutes: 0 是否可以禁用连接池?
A: 设为 0 表示每次都新建(无 TTL 限制),实际上是将"冷启动"变为预期行为,可以作为临时绕过手段,代价是放弃性能优化。