fix: 后端会话过期时重建连接,避免 tools/list 永久为空 - #5
Merged
Conversation
SSE/HTTP 后端空闲后会话过期,其结果不是 transport 进入 ERROR,而是以 JSON-RPC -32001 错误返回。此前该错误被当作普通 Error,携带过期会话的 连接被原样放回池中反复复用,导致 tools/list 长期返回空。 - 识别 -32001 及 "session not found/expired" 消息,标记为会话过期 - 连接级错误判断纳入会话过期,失效陈旧连接而非放回池中 - 工具发现阶段对会话过期做有界重试,透明重建后端会话 - 修复 HttpTransport.doReceive 缺失 continue 导致的队列消息丢失 - 新增会话过期恢复的单元与端到端回归用例 验证:typecheck / lint / format 通过,951 个测试通过。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
修复 #2 中上一轮尚未覆盖的残留场景。上一轮修复解决了「transport 进入 ERROR 后连接池仍复用」的问题,但 SSE/HTTP 后端的会话过期并不会把 transport 置为 ERROR —— 而是以 HTTP 200 返回 JSON-RPC 错误:
{ "code": -32001, "message": "Session not found or expired. Please send initialize again." }此时
tools/list拿到的-32001被当作普通Error,携带过期会话的连接被pool.release()原样放回连接池,导致每次工具发现都复用这条死连接 →tools/list长期返回空。根因
src/routing/tool-router.ts的queryToolsViaMCP把会话过期错误当作普通Error抛出,isConnectionLevelError无法识别,走else分支把连接放回池中。isConnectionHealthy对 http 传输只检查本地isConnected()(永远为 true),从不真正探测后端,因此健康检查发现不了会话已过期。修复
isSessionExpiryError():识别-32001、TransportError('SESSION_EXPIRED'),以及有序匹配/session\b.*\b(not found|expired)/i(避免误判 "tool x not found in session y")。isConnectionLevelError()纳入会话过期 → 复用现有markConnectionFailed失效流程(discovery 与tools/call两条路径均覆盖)。queryServiceTools()会话过期时失效连接并做有界重试(上界maxConnections + 1),在同一请求内透明重建后端会话;非会话的连接错误仍快速失败。HttpTransport.doReceive缺失continue(stdio 版本有),避免 messageQueue 积压 ≥2 条消息时第二条响应被卡死导致 10s 超时。验证
npm run typecheck/lint/format:check通过npm test:951 个测试通过(新增 7 个回归/集成用例)tools/list从工具恢复为3 工具Closes #2