File size: 3,166 Bytes
b88ce1b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import logger from './logger.js';

/**
 * 空闲模式管理器
 * 在没有请求时降低内存使用,减少后台活动
 */
class IdleManager {
  constructor() {
    this.lastRequestTime = Date.now();
    this.idleTimeout = 30 * 1000; // 30秒无请求后进入空闲模式(极致优化)
    this.isIdle = false;
    this.gcInterval = null;
    this.checkInterval = null;

    // 启动空闲检查
    this.startIdleCheck();

    // 10秒后立即检查是否应该进入空闲模式
    setTimeout(() => {
      const idleTime = Date.now() - this.lastRequestTime;
      if (idleTime > this.idleTimeout) {
        this.enterIdleMode();
      }
    }, 10000);
  }

  /**
   * 记录请求活动
   */
  recordActivity() {
    this.lastRequestTime = Date.now();

    // 如果之前是空闲状态,现在恢复活跃
    if (this.isIdle) {
      this.exitIdleMode();
    }
  }

  /**
   * 启动空闲检查
   */
  startIdleCheck() {
    // 每15秒检查一次是否应该进入空闲模式
    this.checkInterval = setInterval(() => {
      const idleTime = Date.now() - this.lastRequestTime;

      if (!this.isIdle && idleTime > this.idleTimeout) {
        this.enterIdleMode();
      }
    }, 15000); // 每15秒检查一次(更频繁)

    // 不阻止进程退出
    this.checkInterval.unref();
  }

  /**
   * 进入空闲模式
   */
  enterIdleMode() {
    if (this.isIdle) return;

    logger.info('⏸️  进入空闲模式 - 降低资源使用');
    this.isIdle = true;

    // 触发垃圾回收
    if (global.gc) {
      global.gc();
      logger.info('🗑️  已触发垃圾回收');
    } else {
      // 如果没有启用 --expose-gc,尝试通过其他方式释放内存
      logger.warn('⚠️  未启用 --expose-gc,建议使用 node --expose-gc 启动以获得更好的内存优化');
    }

    // 在空闲模式下,每2分钟进行一次垃圾回收(更频繁)
    this.gcInterval = setInterval(() => {
      if (global.gc) {
        global.gc();
        logger.info('🗑️  空闲模式:定期垃圾回收');
      }
    }, 2 * 60 * 1000); // 每2分钟一次

    // 不阻止进程退出
    this.gcInterval.unref();
  }

  /**
   * 退出空闲模式
   */
  exitIdleMode() {
    if (!this.isIdle) return;

    logger.info('▶️  退出空闲模式 - 恢复正常运行');
    this.isIdle = false;

    // 清除空闲模式的定时器
    if (this.gcInterval) {
      clearInterval(this.gcInterval);
      this.gcInterval = null;
    }

    // 触发一次垃圾回收,清理空闲期间的内存
    if (global.gc) {
      global.gc();
    }
  }

  /**
   * 获取当前状态
   */
  getStatus() {
    const idleTime = Date.now() - this.lastRequestTime;
    return {
      isIdle: this.isIdle,
      idleTimeSeconds: Math.floor(idleTime / 1000),
      lastRequestTime: new Date(this.lastRequestTime).toISOString()
    };
  }

  /**
   * 清理资源
   */
  destroy() {
    if (this.checkInterval) {
      clearInterval(this.checkInterval);
    }
    if (this.gcInterval) {
      clearInterval(this.gcInterval);
    }
  }
}

const idleManager = new IdleManager();
export default idleManager;