Skip to content

changelog 称「首次使用时启动」,但 MCP 进程实际仍在 session_start 时 spawn #1

Description

@xhl592576605

感谢这个扩展,跨项目 ctx.cwd 修复 + 三路径清理僵尸进程非常好用 👍

想反馈一个 changelog 与实现不一致的点。

环境

  • pi-codegraph-fix 1.1.01.1.1(两者 extensions/index.tsdiff 完全相同)

changelog 原文

懒加载: codegraph MCP 进程从 session_start 改到首次使用时后台启动,启动不再阻塞

问题

  • "启动不再阻塞" —— ✅ 做到了:client.start().then(...) 没有 awaitsession_start hook 立即返回。
  • "从 session_start 改到首次使用时后台启动" —— ❌ 没有落地:spawn 仍然发生在 session_start 事件里。
pi.on("session_start", async (_event, ctx) => {
    ...
    if (!existsSync(dbPath)) return;
    if (clients.has(projectRoot)) { projectReady = true; return; }

    const client = new McpClient();

    // Fire-and-forget: lazy connect — don't block session_start
    client.start(projectRoot).then(async () => {   // ← spawn 仍在 session_start
      clients.set(projectRoot, client);
      ensureCleanup(clients);
      const tools = await client.listTools();
      for (const tool of tools) {
        pi.registerTool({ ... })
      }
      projectReady = true;
    })
});

client.start() 内部就是 spawn(bin, ["serve", "--mcp"]),会话一建立进程就起来了,并不等待"首次使用"。

实测验证

开一个 pi 会话、全程不主动调用任何 codegraph 工具,ps 已经能看到 sidecar 常驻:

pi(88049) → codegraph serve --mcp(88065) → 内部(88094) → daemon(88098)

如果是"首次使用才启动",那么在首次调用 codegraph_explore 之前,根本不该存在该进程。

区分两个概念

优化点 是否做到
session_start hook 不阻塞(fire-and-forget)
推迟到首次工具调用才 spawn

"fire-and-forget(不阻塞 hook)" 与 "推迟到首次使用" 是两个不同维度,当前 changelog 把前者描述成了后者。

建议

方向 A(改实现,做到名副其实的懒加载):把 spawn 挪进工具 execute,用 Promise 缓存延迟到首次调用:

let clientPromise: Promise<McpClient> | null = null
const getClient = (cwd: string) =>
  (clientPromise ??= new McpClient().start(cwd))

// session_start 只做:检查 db 是否存在、注册工具壳,不 spawn
// 工具 execute:
execute: async (_id, params) => {
  const client = await getClient(projectRoot)   // ← 真正的懒加载触发点
  return client.call("tools/call", { name: tool.name, arguments: params })
}

注意:方向 A 需要处理工具注册时机——因为 tools/list 依赖 MCP 握手完成,可能要保留一个已知工具名白名单(codegraph_explore 等)提前注册壳,首次调用时再握手。

方向 B(改 changelog 措辞):把"从 session_start 改到首次使用时"去掉,保留"fire-and-forget,不阻塞 session_start"即可。

任选其一即可让文档与实现一致。再次感谢这个实用的扩展 🙏

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions