[P1/高] ConfirmationHook waitForConfirmation 超时竞态条件 #18

Open
opened 2026-07-21 21:55:47 +08:00 by thzxx · 0 comments
Owner

问题类型

缺陷 / 高 / IPC 通信

文件位置

electron/harness/hooks/confirmation-hook.ts

问题描述

waitForConfirmation 使用 Promise + setTimeout 实现超时控制。
当超时与用户确认同时发生时(race condition):

  1. 超时定时器已触发,reject
  2. 同时用户点击确认,resolve
  3. Promise 状态由先到者决定,但 pending 的回调可能仍执行
  4. 内存泄漏:未清理的定时器与监听器

project_memory.md 要求:

Tool confirmation timeout is configurable via agent.confirmationTimeoutMs (30s~600s, default 120s)

影响

  • 工具执行状态不一致
  • 内存泄漏
  • 用户确认被忽略

建议修复

async waitForConfirmation(requestId: string): Promise<boolean> {
  // 使用 AbortController 统一清理
  const controller = new AbortController();
  const timer = setTimeout(() => {
    controller.abort();
  }, this.timeoutMs);

  try {
    const result = await new Promise<boolean>((resolve, reject) => {
      const onConfirm = (id: string, approved: boolean) => {
        if (id === requestId) {
          this.off('confirmation', onConfirm);
          resolve(approved);
        }
      };
      this.on('confirmation', onConfirm);

      controller.signal.addEventListener('abort', () => {
        this.off('confirmation', onConfirm);
        resolve(false); // 超时视为拒绝
      });
    });
    return result;
  } finally {
    clearTimeout(timer);
  }
}

确保监听器与定时器都被清理。

## 问题类型 缺陷 / 高 / IPC 通信 ## 文件位置 `electron/harness/hooks/confirmation-hook.ts` ## 问题描述 waitForConfirmation 使用 Promise + setTimeout 实现超时控制。 当超时与用户确认同时发生时(race condition): 1. 超时定时器已触发,reject 2. 同时用户点击确认,resolve 3. Promise 状态由先到者决定,但 pending 的回调可能仍执行 4. 内存泄漏:未清理的定时器与监听器 project_memory.md 要求: > Tool confirmation timeout is configurable via `agent.confirmationTimeoutMs` (30s~600s, default 120s) ## 影响 - 工具执行状态不一致 - 内存泄漏 - 用户确认被忽略 ## 建议修复 ```ts async waitForConfirmation(requestId: string): Promise<boolean> { // 使用 AbortController 统一清理 const controller = new AbortController(); const timer = setTimeout(() => { controller.abort(); }, this.timeoutMs); try { const result = await new Promise<boolean>((resolve, reject) => { const onConfirm = (id: string, approved: boolean) => { if (id === requestId) { this.off('confirmation', onConfirm); resolve(approved); } }; this.on('confirmation', onConfirm); controller.signal.addEventListener('abort', () => { this.off('confirmation', onConfirm); resolve(false); // 超时视为拒绝 }); }); return result; } finally { clearTimeout(timer); } } ``` 确保监听器与定时器都被清理。
thzxx added the IPC????? labels 2026-07-21 21:55:47 +08:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: MetonaTeam/metona-ai-desktop#18