api缓存删除失败bug预修复
This commit is contained in:
+108
-21
@@ -3,6 +3,7 @@ const path = require('path');
|
|||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const CacheConfigManager = require('../config/cache-config');
|
const CacheConfigManager = require('../config/cache-config');
|
||||||
const { defaultLogger } = require('../utils/logger');
|
const { defaultLogger } = require('../utils/logger');
|
||||||
|
const FileUtils = require('../utils/file-utils');
|
||||||
|
|
||||||
// 创建logger实例
|
// 创建logger实例
|
||||||
const logger = defaultLogger.child('ApiCacheService');
|
const logger = defaultLogger.child('ApiCacheService');
|
||||||
@@ -297,13 +298,22 @@ class ApiCacheService {
|
|||||||
// 计算总大小和收集文件信息
|
// 计算总大小和收集文件信息
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const filePath = path.join(this.cacheDir, file);
|
const filePath = path.join(this.cacheDir, file);
|
||||||
const stats = await fs.stat(filePath);
|
try {
|
||||||
totalSize += stats.size;
|
const stats = await fs.stat(filePath);
|
||||||
fileStats.push({
|
totalSize += stats.size;
|
||||||
path: filePath,
|
fileStats.push({
|
||||||
size: stats.size,
|
path: filePath,
|
||||||
mtime: stats.mtime
|
size: stats.size,
|
||||||
});
|
mtime: stats.mtime
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
// 如果文件不存在,跳过
|
||||||
|
if (error.code === 'ENOENT') {
|
||||||
|
logger.debug(`API缓存文件不存在,跳过: ${filePath}`);
|
||||||
|
} else {
|
||||||
|
logger.debug(`检查API缓存文件失败: ${filePath}`, error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果超过最大大小,删除最旧的文件
|
// 如果超过最大大小,删除最旧的文件
|
||||||
@@ -314,8 +324,13 @@ class ApiCacheService {
|
|||||||
fileStats.sort((a, b) => a.mtime.getTime() - b.mtime.getTime());
|
fileStats.sort((a, b) => a.mtime.getTime() - b.mtime.getTime());
|
||||||
|
|
||||||
for (const file of fileStats) {
|
for (const file of fileStats) {
|
||||||
await fs.unlink(file.path);
|
const deleteSuccess = await FileUtils.safeDeleteFile(file.path);
|
||||||
totalSize -= file.size;
|
if (deleteSuccess) {
|
||||||
|
totalSize -= file.size;
|
||||||
|
logger.debug(`删除过大API缓存文件: ${file.path}`);
|
||||||
|
} else {
|
||||||
|
logger.debug(`删除过大API缓存文件失败: ${file.path}`);
|
||||||
|
}
|
||||||
|
|
||||||
if (totalSize <= this.config.maxSize * 0.8) { // 清理到80%
|
if (totalSize <= this.config.maxSize * 0.8) { // 清理到80%
|
||||||
break;
|
break;
|
||||||
@@ -337,20 +352,60 @@ class ApiCacheService {
|
|||||||
try {
|
try {
|
||||||
const files = await fs.readdir(this.cacheDir);
|
const files = await fs.readdir(this.cacheDir);
|
||||||
let cleanedCount = 0;
|
let cleanedCount = 0;
|
||||||
|
let errorCount = 0;
|
||||||
|
let skippedCount = 0;
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const filePath = path.join(this.cacheDir, file);
|
const filePath = path.join(this.cacheDir, file);
|
||||||
const stats = await fs.stat(filePath);
|
try {
|
||||||
|
const stats = await fs.stat(filePath);
|
||||||
|
|
||||||
const age = Date.now() - stats.mtime.getTime();
|
const age = now - stats.mtime.getTime();
|
||||||
if (age > this.config.maxAge) {
|
if (age > this.config.maxAge) {
|
||||||
await fs.unlink(filePath);
|
// 简单的文件占用检查(仅在Windows上)
|
||||||
cleanedCount++;
|
if (process.platform === 'win32') {
|
||||||
|
try {
|
||||||
|
// 尝试以独占模式打开文件来检查是否被占用
|
||||||
|
const handle = await fs.open(filePath, 'r');
|
||||||
|
await handle.close();
|
||||||
|
} catch (openError) {
|
||||||
|
if (openError.code === 'EBUSY' || openError.code === 'EPERM') {
|
||||||
|
logger.debug(`跳过被占用的过期API缓存文件: ${filePath}`);
|
||||||
|
skippedCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用改进的安全删除方法
|
||||||
|
const deleteSuccess = await FileUtils.safeDeleteFile(filePath);
|
||||||
|
if (deleteSuccess) {
|
||||||
|
cleanedCount++;
|
||||||
|
logger.debug(`成功删除过期API缓存文件: ${filePath}`);
|
||||||
|
} else {
|
||||||
|
errorCount++;
|
||||||
|
// 减少日志噪音,只在debug级别记录
|
||||||
|
logger.debug(`删除过期API缓存文件失败: ${filePath}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// 如果文件不存在,静默忽略
|
||||||
|
if (error.code === 'ENOENT') {
|
||||||
|
logger.debug(`过期API缓存文件不存在,跳过: ${filePath}`);
|
||||||
|
} else {
|
||||||
|
logger.debug(`检查过期API缓存文件失败: ${filePath}`, error.message);
|
||||||
|
errorCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleanedCount > 0) {
|
if (cleanedCount > 0 || errorCount > 0 || skippedCount > 0) {
|
||||||
logger.info(`清理了 ${cleanedCount} 个过期API缓存文件`);
|
if (errorCount === 0 && skippedCount === 0) {
|
||||||
|
logger.info(`清理了 ${cleanedCount} 个过期API缓存文件`);
|
||||||
|
} else {
|
||||||
|
logger.info(`API缓存清理完成,成功删除 ${cleanedCount} 个文件,失败 ${errorCount} 个文件,跳过 ${skippedCount} 个被占用文件`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('清理过期API缓存失败:', error);
|
logger.error('清理过期API缓存失败:', error);
|
||||||
@@ -375,13 +430,36 @@ class ApiCacheService {
|
|||||||
async clearAllCache() {
|
async clearAllCache() {
|
||||||
try {
|
try {
|
||||||
const files = await fs.readdir(this.cacheDir);
|
const files = await fs.readdir(this.cacheDir);
|
||||||
|
let cleanedCount = 0;
|
||||||
|
let errorCount = 0;
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const filePath = path.join(this.cacheDir, file);
|
const filePath = path.join(this.cacheDir, file);
|
||||||
await fs.unlink(filePath);
|
try {
|
||||||
|
const deleteSuccess = await FileUtils.safeDeleteFile(filePath);
|
||||||
|
if (deleteSuccess) {
|
||||||
|
cleanedCount++;
|
||||||
|
logger.debug(`删除API缓存文件: ${filePath}`);
|
||||||
|
} else {
|
||||||
|
errorCount++;
|
||||||
|
logger.debug(`删除API缓存文件失败: ${filePath}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// 如果文件不存在,静默忽略
|
||||||
|
if (error.code === 'ENOENT') {
|
||||||
|
logger.debug(`API缓存文件不存在,跳过: ${filePath}`);
|
||||||
|
} else {
|
||||||
|
logger.debug(`删除API缓存文件出错: ${filePath}`, error.message);
|
||||||
|
errorCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info('所有API缓存已清理');
|
if (errorCount === 0) {
|
||||||
|
logger.info(`所有API缓存已清理,共删除 ${cleanedCount} 个文件`);
|
||||||
|
} else {
|
||||||
|
logger.info(`API缓存清理完成,成功删除 ${cleanedCount} 个文件,失败 ${errorCount} 个文件`);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('清理所有API缓存失败:', error);
|
logger.error('清理所有API缓存失败:', error);
|
||||||
throw error;
|
throw error;
|
||||||
@@ -400,9 +478,18 @@ class ApiCacheService {
|
|||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
const filePath = path.join(this.cacheDir, file);
|
const filePath = path.join(this.cacheDir, file);
|
||||||
const stats = await fs.stat(filePath);
|
try {
|
||||||
totalSize += stats.size;
|
const stats = await fs.stat(filePath);
|
||||||
fileCount++;
|
totalSize += stats.size;
|
||||||
|
fileCount++;
|
||||||
|
} catch (error) {
|
||||||
|
// 如果文件不存在,跳过
|
||||||
|
if (error.code === 'ENOENT') {
|
||||||
|
logger.debug(`API缓存文件不存在,跳过: ${filePath}`);
|
||||||
|
} else {
|
||||||
|
logger.debug(`检查API缓存文件失败: ${filePath}`, error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user