File size: 3,652 Bytes
a0b676c |
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 |
// 简单内存缓存:按 sessionId + model 维度缓存思维链签名和工具签名
// 同时集成内存管理器,在压力较高时自动收缩/清空缓存
import memoryManager, { MemoryPressure } from './memoryManager.js';
const reasoningSignatureCache = new Map();
const toolSignatureCache = new Map();
// 正常情况下允许的最大条目数(低压力时)
const MAX_REASONING_ENTRIES = 256;
const MAX_TOOL_ENTRIES = 256;
// 过期时间与定时清理间隔(毫秒)
const ENTRY_TTL_MS = 30 * 60 * 1000; // 30 分钟
const CLEAN_INTERVAL_MS = 10 * 60 * 1000; // 每 10 分钟扫一遍
function makeKey(sessionId, model) {
return `${sessionId || ''}::${model || ''}`;
}
function pruneMap(map, targetSize) {
if (map.size <= targetSize) return;
const removeCount = map.size - targetSize;
let removed = 0;
for (const key of map.keys()) {
map.delete(key);
removed++;
if (removed >= removeCount) break;
}
}
function pruneExpired(map, now) {
for (const [key, entry] of map.entries()) {
if (!entry || typeof entry.ts !== 'number') continue;
if (now - entry.ts > ENTRY_TTL_MS) {
map.delete(key);
}
}
}
// 注册到内存管理器,在不同压力级别下自动清理缓存
memoryManager.registerCleanup((pressure) => {
if (pressure === MemoryPressure.MEDIUM) {
// 中等压力:收缩到一半容量
pruneMap(reasoningSignatureCache, Math.floor(MAX_REASONING_ENTRIES / 2));
pruneMap(toolSignatureCache, Math.floor(MAX_TOOL_ENTRIES / 2));
} else if (pressure === MemoryPressure.HIGH) {
// 高压力:大幅收缩
pruneMap(reasoningSignatureCache, Math.floor(MAX_REASONING_ENTRIES / 4));
pruneMap(toolSignatureCache, Math.floor(MAX_TOOL_ENTRIES / 4));
} else if (pressure === MemoryPressure.CRITICAL) {
// 紧急压力:直接清空,优先保活
reasoningSignatureCache.clear();
toolSignatureCache.clear();
}
});
// 定时清理:不依赖压力等级,按 TTL 移除过期签名
setInterval(() => {
const now = Date.now();
pruneExpired(reasoningSignatureCache, now);
pruneExpired(toolSignatureCache, now);
}, CLEAN_INTERVAL_MS).unref?.();
export function setReasoningSignature(sessionId, model, signature) {
if (!signature) return;
const key = makeKey(sessionId, model);
reasoningSignatureCache.set(key, { signature, ts: Date.now() });
// 防止在低压力下无限增长
pruneMap(reasoningSignatureCache, MAX_REASONING_ENTRIES);
}
export function getReasoningSignature(sessionId, model) {
const key = makeKey(sessionId, model);
const entry = reasoningSignatureCache.get(key);
if (!entry) return null;
const now = Date.now();
if (typeof entry.ts === 'number' && now - entry.ts > ENTRY_TTL_MS) {
reasoningSignatureCache.delete(key);
return null;
}
return entry.signature || null;
}
export function setToolSignature(sessionId, model, signature) {
if (!signature) return;
const key = makeKey(sessionId, model);
toolSignatureCache.set(key, { signature, ts: Date.now() });
pruneMap(toolSignatureCache, MAX_TOOL_ENTRIES);
}
export function getToolSignature(sessionId, model) {
const key = makeKey(sessionId, model);
const entry = toolSignatureCache.get(key);
if (!entry) return null;
const now = Date.now();
if (typeof entry.ts === 'number' && now - entry.ts > ENTRY_TTL_MS) {
toolSignatureCache.delete(key);
return null;
}
return entry.signature || null;
}
// 预留:手动清理接口(目前未在外部使用,但方便将来扩展)
export function clearThoughtSignatureCaches() {
reasoningSignatureCache.clear();
toolSignatureCache.clear();
}
|