修复: 添加分享缓存过期机制(TTL)
问题描述: - 分享文件缓存使用Map没有过期机制 - 缓存会无限增长,占用内存 - 文件更新或删除后缓存不会自动清除 - 长期运行可能导致内存泄漏 修复内容: 1. 实现TTLCache类 - 支持自定义过期时间(默认1小时) - 自动检查缓存是否过期 - API完全兼容Map(set/get/has/delete) 2. 添加自动清理机制 - 每10分钟自动清理过期缓存 - 记录清理日志便于监控 - 提供destroy方法停止清理定时器 3. 替换shareFileCache为TTLCache实例 - 设置1小时TTL - 无需修改现有代码 - 向后兼容所有现有使用 缓存特性: - get()时自动检查过期 - has()时自动检查过期 - 定期清理避免内存积累 - size()方法获取当前缓存数量 影响范围: 分享文件缓存管理 测试建议: - 验证分享链接访问后缓存生效 - 验证1小时后缓存自动失效 - 监控日志确认定期清理执行 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -63,9 +63,91 @@ const upload = multer({
|
||||
limits: { fileSize: 5 * 1024 * 1024 * 1024 } // 5GB限制
|
||||
});
|
||||
|
||||
// 分享文件信息缓存(内存缓存)
|
||||
// 格式: Map<share_code, { name, size, sizeFormatted, modifiedAt, httpDownloadUrl }>
|
||||
const shareFileCache = new Map();
|
||||
// ===== TTL缓存类 =====
|
||||
|
||||
// 带过期时间的缓存类
|
||||
class TTLCache {
|
||||
constructor(defaultTTL = 3600000) { // 默认1小时
|
||||
this.cache = new Map();
|
||||
this.defaultTTL = defaultTTL;
|
||||
|
||||
// 每10分钟清理一次过期缓存
|
||||
this.cleanupInterval = setInterval(() => {
|
||||
this.cleanup();
|
||||
}, 10 * 60 * 1000);
|
||||
}
|
||||
|
||||
set(key, value, ttl = this.defaultTTL) {
|
||||
const expiresAt = Date.now() + ttl;
|
||||
this.cache.set(key, { value, expiresAt });
|
||||
}
|
||||
|
||||
get(key) {
|
||||
const item = this.cache.get(key);
|
||||
if (!item) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// 检查是否过期
|
||||
if (Date.now() > item.expiresAt) {
|
||||
this.cache.delete(key);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return item.value;
|
||||
}
|
||||
|
||||
has(key) {
|
||||
const item = this.cache.get(key);
|
||||
if (!item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否过期
|
||||
if (Date.now() > item.expiresAt) {
|
||||
this.cache.delete(key);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
delete(key) {
|
||||
return this.cache.delete(key);
|
||||
}
|
||||
|
||||
// 清理过期缓存
|
||||
cleanup() {
|
||||
const now = Date.now();
|
||||
let cleaned = 0;
|
||||
|
||||
for (const [key, item] of this.cache.entries()) {
|
||||
if (now > item.expiresAt) {
|
||||
this.cache.delete(key);
|
||||
cleaned++;
|
||||
}
|
||||
}
|
||||
|
||||
if (cleaned > 0) {
|
||||
console.log(`[缓存清理] 已清理 ${cleaned} 个过期的分享缓存`);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取缓存大小
|
||||
size() {
|
||||
return this.cache.size;
|
||||
}
|
||||
|
||||
// 停止清理定时器
|
||||
destroy() {
|
||||
if (this.cleanupInterval) {
|
||||
clearInterval(this.cleanupInterval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分享文件信息缓存(内存缓存,1小时TTL)
|
||||
const shareFileCache = new TTLCache(60 * 60 * 1000);
|
||||
|
||||
// ===== 工具函数 =====
|
||||
|
||||
|
||||
Reference in New Issue
Block a user