refactor(缓存): 优化缩略图生成和缓存文件命名逻辑

- 修改缓存元文件名使用 uniqidhex 替代 uniqid 以保持一致性
- 重构 createThumbnail 函数,使其返回缩略图路径并改进参数处理
- 移除冗余的缩略图文件存在性检查,改为统一在函数内处理
- 改进缩略图尺寸检查逻辑,增加有效性验证
- 优化缩略图 ETag 生成方式,优先使用 thumb.uniqid
This commit is contained in:
XiaoMo 2025-05-27 17:50:48 +08:00
parent 650a7b8852
commit 59f7551913
2 changed files with 19 additions and 29 deletions

File diff suppressed because one or more lines are too long

View File

@ -85,7 +85,6 @@ setInterval(() => {
for (const key in pathIndex) {
if (currentTime - pathIndex[key].timestamp > CACHE_EXPIRY_MS) {
delete pathIndex[key];
// Consider deleting actual cache files as well if not managed elsewhere
}
}
}, CACHE_CLEANUP_INTERVAL_MS);
@ -144,7 +143,7 @@ async function processSuccessfulApiData(apiData, uniqidhex, reqPath, token, sign
const data = { realUrl, cloudtype, expiration: expiration * 1000, path: apiPath, headers, uniqid, thumb };
pathIndex[uniqidhex] = { uniqid: data.uniqid, timestamp: Date.now() };
const cacheMetaFile = pathModule.join(cacheDir, `${data.uniqid}.meta`);
const cacheMetaFile = pathModule.join(cacheDir, `${uniqidhex}.meta`);
const cacheContentFile = pathModule.join(cacheDir, `${data.uniqid}.content`);
const tempCacheContentFile = pathModule.join(cacheDir, `${data.uniqid}_${crypto.randomBytes(16).toString('hex')}.temp`);
@ -172,7 +171,7 @@ async function processSuccessfulApiData(apiData, uniqidhex, reqPath, token, sign
async function tryServeFromStaleCacheOrError(uniqidhex, res, errorMessage) {
if (pathIndex[uniqidhex]) {
const cacheMetaFile = pathModule.join(cacheDir, `${pathIndex[uniqidhex].uniqid}.meta`);
const cacheMetaFile = pathModule.join(cacheDir, `${uniqidhex}.meta`);
const cacheContentFile = pathModule.join(cacheDir, `${pathIndex[uniqidhex].uniqid}.content`);
if (fs.existsSync(cacheMetaFile) && fs.existsSync(cacheContentFile)) {
console.warn(`API call failed or returned non-200. Serving stale cache for ${uniqidhex}`);
@ -215,7 +214,7 @@ async function handleMainRequest(req, res) {
let cacheContentFile = '';
if (pathIndex[uniqidhex]) {
cacheMetaFile = pathModule.join(cacheDir, `${pathIndex[uniqidhex].uniqid}.meta`);
cacheMetaFile = pathModule.join(cacheDir, `${uniqidhex}.meta`);
cacheContentFile = pathModule.join(cacheDir, `${pathIndex[uniqidhex].uniqid}.content`);
}
@ -377,22 +376,19 @@ async function fetchApiData(reqPath, token, sign) {
}
// createThumbnail
function createThumbnail(data, cacheContentFile, thumbCacheFile) {
function createThumbnail(data, cacheContentFile) {
const { path, thumb } = data;
const thumbCacheFile = pathModule.join(cacheDir, `thumb_${thumb.uniqid}.jpeg`);
if (fs.existsSync(thumbCacheFile)) return thumbCacheFile;
const isVideo = path && typeof path === 'string' && path.includes('.mp4');
if (isVideo || !thumb) return;
if (fs.existsSync(thumbCacheFile)) return;
const width = thumb.width;
const height = thumb.height;
sharp(cacheContentFile)
.resize(width, height)
.toFile(thumbCacheFile, (err, info) => {
if (err) {
console.error(`Error creating thumbnail for ${cacheContentFile}:`, err);
return;
}
});
const width = thumb.width && thumb.width > 0 ? thumb.width : undefined;
const height = thumb.height && thumb.height > 0 ? thumb.height : undefined;
if (!width) return;
sharp(cacheContentFile).resize(width, height).toFile(thumbCacheFile);
return thumbCacheFile;
}
@ -461,13 +457,9 @@ const fetchAndServe = (data, tempCacheContentFile, cacheContentFile, cacheMetaFi
fs.renameSync(tempCacheContentFile, cacheContentFile);
console.log(`Successfully cached: ${cacheContentFile}`);
// 生成缩略图
if (data.thumb) {
const thumbCacheFile = pathModule.join(cacheDir, `${data.uniqid}_thumb.jpg`);
if (!fs.existsSync(thumbCacheFile)) {
// 创建缩略图
createThumbnail(data, cacheContentFile, thumbCacheFile);
}
createThumbnail(data, cacheContentFile);
}
} catch (renameError) {
console.error(`Error renaming temp cache file ${tempCacheContentFile} to ${cacheContentFile}:`, renameError);
@ -514,21 +506,19 @@ function serveFromCache(cacheData, cacheContentFile, cacheMetaFile, res) {
'Last-Modified': (cacheData.headers && cacheData.headers['last-modified']) || new Date(fs.statSync(cacheMetaFile).mtime).toUTCString(),
};
if (cacheData.thumb) {
const thumbCacheFile = pathModule.join(cacheDir, `${cacheData.uniqid}_thumb.jpg`);
if (fs.existsSync(thumbCacheFile)) {
var thumbCacheFile = createThumbnail(cacheData, cacheContentFile)
if (thumbCacheFile && fs.existsSync(thumbCacheFile)) {
cacheData.headers['content-length'] = fs.statSync(thumbCacheFile).size;
const responseHeaders = {
...baseHeaders,
...(cacheData.headers || {}),
'ETag': (cacheData.uniqid || '') + '_thumb',
'ETag': (cacheData.thumb.uniqid || cacheData.uniqid) + '_thumb',
'Content-Type': 'image/jpeg',
};
res.writeHead(HTTP_STATUS.OK, responseHeaders);
const thumbStream = fs.createReadStream(thumbCacheFile);
thumbStream.pipe(res);
return;
} else {
createThumbnail(cacheData, cacheContentFile, thumbCacheFile)
}
}