oak-cli/lib/server/timer-manager.js

163 lines
5.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
// timer-manager.ts
Object.defineProperty(exports, "__esModule", { value: true });
exports.getTimerStats = exports.clearAllTimers = exports.unhookTimers = exports.hookTimers = exports.timerManager = void 0;
class GlobalTimerManager {
timers = new Map();
isHooked = false;
// 保存原始函数
original = {
setTimeout: global.setTimeout,
setInterval: global.setInterval,
setImmediate: global.setImmediate, clearTimeout: global.clearTimeout,
clearInterval: global.clearInterval,
clearImmediate: global.clearImmediate,
};
/**
* 开始拦截全局定时器
*/
hook() {
if (this.isHooked) {
console.warn('[TimerManager] Already hooked');
return;
}
const self = this;
// Hook setTimeout
global.setTimeout = function (callback, ms, ...args) {
const id = self.original.setTimeout((...callbackArgs) => {
self.timers.delete(id); // 执行完后移除
callback(...callbackArgs);
}, ms, ...args);
self.timers.set(id, {
id,
type: 'timeout',
createdAt: Date.now(),
});
return id;
};
// Hook setInterval
global.setInterval = function (callback, ms, ...args) {
const id = self.original.setInterval(callback, ms, ...args);
self.timers.set(id, {
id,
type: 'interval',
createdAt: Date.now(),
});
return id;
};
// Hook setImmediate
global.setImmediate = function (callback, ...args) {
const id = self.original.setImmediate((...callbackArgs) => {
self.timers.delete(id); // 执行完后移除
callback(...callbackArgs);
}, ...args);
self.timers.set(id, {
id,
type: 'immediate',
createdAt: Date.now(),
});
return id;
};
// Hook clear方法确保从追踪中移除
global.clearTimeout = ((id) => {
self.timers.delete(id);
return self.original.clearTimeout(id);
});
global.clearInterval = ((id) => {
self.timers.delete(id);
return self.original.clearInterval(id);
});
global.clearImmediate = ((id) => {
self.timers.delete(id);
return self.original.clearImmediate(id);
});
this.isHooked = true;
console.log('[TimerManager] Hooked global timer functions');
}
/**
* 恢复原始的全局定时器函数
*/
unhook() {
if (!this.isHooked) {
return;
}
global.setTimeout = this.original.setTimeout;
global.setInterval = this.original.setInterval;
global.setImmediate = this.original.setImmediate;
global.clearTimeout = this.original.clearTimeout;
global.clearInterval = this.original.clearInterval;
global.clearImmediate = this.original.clearImmediate;
this.isHooked = false;
}
/**
* 清除所有被追踪的定时器
*/
clearAll() {
const count = this.timers.size;
this.timers.forEach((record) => {
if (record.type === 'immediate') {
this.original.clearImmediate.call(null, record.id);
}
else {
this.original.clearTimeout.call(null, record.id);
}
});
this.timers.clear();
return count;
}
/**
* 按类型清除定时器
*/
clearByType(type) {
let count = 0;
this.timers.forEach((record, id) => {
if (record.type === type) {
if (type === 'immediate') {
this.original.clearImmediate.call(null, id);
}
else {
this.original.clearTimeout.call(null, id);
}
this.timers.delete(id);
count++;
}
});
return count;
}
/**
* 获取当前活跃的定时器数量
*/
getActiveCount() {
return this.timers.size;
}
/**
* 获取定时器统计信息
*/
getStats() {
const stats = {
timeout: 0,
interval: 0,
immediate: 0,
};
this.timers.forEach((record) => {
stats[record.type]++;
});
return stats;
}
/**
* 获取所有定时器的详细信息(用于调试)
*/
getTimers() {
return Array.from(this.timers.values());
}
}
exports.timerManager = new GlobalTimerManager();
const hookTimers = () => exports.timerManager.hook();
exports.hookTimers = hookTimers;
const unhookTimers = () => exports.timerManager.unhook();
exports.unhookTimers = unhookTimers;
const clearAllTimers = () => exports.timerManager.clearAll();
exports.clearAllTimers = clearAllTimers;
const getTimerStats = () => exports.timerManager.getStats();
exports.getTimerStats = getTimerStats;