fix(agents): 修复 EventBus 订阅泄漏风险断裂点

- EventBusSubscriptions 新增 count() 方法统计订阅数
- EventBus.subscribe() 添加订阅计数监控,超过 100 时发出警告
- 在 JSDoc 中明确说明需要手动调用 unsubscribe 以防止内存泄漏
This commit is contained in:
wing
2026-02-15 04:30:27 +08:00
parent 0c8c885c3f
commit d3ab7d1739
2 changed files with 48 additions and 1 deletions
+35
View File
@@ -224,6 +224,41 @@ export class EventBusSubscriptions {
return handlers;
}
/**
* 统计指定事件类型的订阅数量
* @param {string} eventType - 事件类型
* @returns {number} 订阅数量
*/
count(eventType) {
let total = 0;
// 精确匹配 - 普通
const direct = this._listeners.get(eventType);
if (direct) total += direct.size;
// 精确匹配 - 优先级
const priorityMap = this._priorityListeners.get(eventType);
if (priorityMap) {
for (const set of priorityMap.values()) {
total += set.size;
}
}
// 通配符 - 普通
const wildcardSet = this._wildcardListeners.get(eventType);
if (wildcardSet) total += wildcardSet.size;
// 通配符 - 优先级
const wildcardPriorityMap = this._wildcardPriorityListeners.get(eventType);
if (wildcardPriorityMap) {
for (const set of wildcardPriorityMap.values()) {
total += set.size;
}
}
return total;
}
/**
* @returns {void}
*/
+13 -1
View File
@@ -245,13 +245,25 @@ export class EventBus {
/**
* 高级订阅(支持优先级和 AbortSignal
*
* ⚠️ 内存泄漏风险:必须手动调用返回的 unsubscribe 函数以释放监听器。
* 未调用 unsubscribe 会导致监听器累积,造成内存泄漏。
*
* @param {string} eventType - 事件类型
* @param {EventHandler} handler - 处理函数
* @param {{ priority?: number, signal?: AbortSignal }} [options] - { priority, signal }
* @returns {() => void} 取消订阅函数
*/
subscribe(eventType, handler, options = {}) {
return this._subscriptions.subscribe(eventType, handler, options);
const unsub = this._subscriptions.subscribe(eventType, handler, options);
// 监控订阅数,检测潜在泄漏
const count = this._subscriptions.count(eventType);
if (count > 100) {
logger.warn(`High subscription count for ${eventType}: ${count}. Potential memory leak - ensure unsubscribe is called.`);
}
return unsub;
}
/**