refactor(缓存): 优化缩略图生成和缓存文件命名逻辑
- 修改缓存元文件名使用 uniqidhex 替代 uniqid 以保持一致性 - 重构 createThumbnail 函数,使其返回缩略图路径并改进参数处理 - 移除冗余的缩略图文件存在性检查,改为统一在函数内处理 - 改进缩略图尺寸检查逻辑,增加有效性验证 - 优化缩略图 ETag 生成方式,优先使用 thumb.uniqid
This commit is contained in:
parent
650a7b8852
commit
59f7551913
46
source.js
46
source.js
@ -85,7 +85,6 @@ setInterval(() => {
|
|||||||
for (const key in pathIndex) {
|
for (const key in pathIndex) {
|
||||||
if (currentTime - pathIndex[key].timestamp > CACHE_EXPIRY_MS) {
|
if (currentTime - pathIndex[key].timestamp > CACHE_EXPIRY_MS) {
|
||||||
delete pathIndex[key];
|
delete pathIndex[key];
|
||||||
// Consider deleting actual cache files as well if not managed elsewhere
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, CACHE_CLEANUP_INTERVAL_MS);
|
}, 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 };
|
const data = { realUrl, cloudtype, expiration: expiration * 1000, path: apiPath, headers, uniqid, thumb };
|
||||||
|
|
||||||
pathIndex[uniqidhex] = { uniqid: data.uniqid, timestamp: Date.now() };
|
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 cacheContentFile = pathModule.join(cacheDir, `${data.uniqid}.content`);
|
||||||
const tempCacheContentFile = pathModule.join(cacheDir, `${data.uniqid}_${crypto.randomBytes(16).toString('hex')}.temp`);
|
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) {
|
async function tryServeFromStaleCacheOrError(uniqidhex, res, errorMessage) {
|
||||||
if (pathIndex[uniqidhex]) {
|
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`);
|
const cacheContentFile = pathModule.join(cacheDir, `${pathIndex[uniqidhex].uniqid}.content`);
|
||||||
if (fs.existsSync(cacheMetaFile) && fs.existsSync(cacheContentFile)) {
|
if (fs.existsSync(cacheMetaFile) && fs.existsSync(cacheContentFile)) {
|
||||||
console.warn(`API call failed or returned non-200. Serving stale cache for ${uniqidhex}`);
|
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 = '';
|
let cacheContentFile = '';
|
||||||
|
|
||||||
if (pathIndex[uniqidhex]) {
|
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`);
|
cacheContentFile = pathModule.join(cacheDir, `${pathIndex[uniqidhex].uniqid}.content`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,22 +376,19 @@ async function fetchApiData(reqPath, token, sign) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// createThumbnail
|
// createThumbnail
|
||||||
function createThumbnail(data, cacheContentFile, thumbCacheFile) {
|
function createThumbnail(data, cacheContentFile) {
|
||||||
const { path, thumb } = data;
|
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');
|
const isVideo = path && typeof path === 'string' && path.includes('.mp4');
|
||||||
if (isVideo || !thumb) return;
|
if (isVideo || !thumb) return;
|
||||||
if (fs.existsSync(thumbCacheFile)) return;
|
const width = thumb.width && thumb.width > 0 ? thumb.width : undefined;
|
||||||
const width = thumb.width;
|
const height = thumb.height && thumb.height > 0 ? thumb.height : undefined;
|
||||||
const height = thumb.height;
|
if (!width) return;
|
||||||
sharp(cacheContentFile)
|
sharp(cacheContentFile).resize(width, height).toFile(thumbCacheFile);
|
||||||
.resize(width, height)
|
return thumbCacheFile;
|
||||||
.toFile(thumbCacheFile, (err, info) => {
|
|
||||||
if (err) {
|
|
||||||
console.error(`Error creating thumbnail for ${cacheContentFile}:`, err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -461,13 +457,9 @@ const fetchAndServe = (data, tempCacheContentFile, cacheContentFile, cacheMetaFi
|
|||||||
fs.renameSync(tempCacheContentFile, cacheContentFile);
|
fs.renameSync(tempCacheContentFile, cacheContentFile);
|
||||||
console.log(`Successfully cached: ${cacheContentFile}`);
|
console.log(`Successfully cached: ${cacheContentFile}`);
|
||||||
|
|
||||||
|
// 生成缩略图
|
||||||
if (data.thumb) {
|
if (data.thumb) {
|
||||||
const thumbCacheFile = pathModule.join(cacheDir, `${data.uniqid}_thumb.jpg`);
|
createThumbnail(data, cacheContentFile);
|
||||||
if (!fs.existsSync(thumbCacheFile)) {
|
|
||||||
// 创建缩略图
|
|
||||||
createThumbnail(data, cacheContentFile, thumbCacheFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (renameError) {
|
} catch (renameError) {
|
||||||
console.error(`Error renaming temp cache file ${tempCacheContentFile} to ${cacheContentFile}:`, 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(),
|
'Last-Modified': (cacheData.headers && cacheData.headers['last-modified']) || new Date(fs.statSync(cacheMetaFile).mtime).toUTCString(),
|
||||||
};
|
};
|
||||||
if (cacheData.thumb) {
|
if (cacheData.thumb) {
|
||||||
const thumbCacheFile = pathModule.join(cacheDir, `${cacheData.uniqid}_thumb.jpg`);
|
var thumbCacheFile = createThumbnail(cacheData, cacheContentFile)
|
||||||
if (fs.existsSync(thumbCacheFile)) {
|
if (thumbCacheFile && fs.existsSync(thumbCacheFile)) {
|
||||||
cacheData.headers['content-length'] = fs.statSync(thumbCacheFile).size;
|
cacheData.headers['content-length'] = fs.statSync(thumbCacheFile).size;
|
||||||
const responseHeaders = {
|
const responseHeaders = {
|
||||||
...baseHeaders,
|
...baseHeaders,
|
||||||
...(cacheData.headers || {}),
|
...(cacheData.headers || {}),
|
||||||
'ETag': (cacheData.uniqid || '') + '_thumb',
|
'ETag': (cacheData.thumb.uniqid || cacheData.uniqid) + '_thumb',
|
||||||
'Content-Type': 'image/jpeg',
|
'Content-Type': 'image/jpeg',
|
||||||
};
|
};
|
||||||
res.writeHead(HTTP_STATUS.OK, responseHeaders);
|
res.writeHead(HTTP_STATUS.OK, responseHeaders);
|
||||||
const thumbStream = fs.createReadStream(thumbCacheFile);
|
const thumbStream = fs.createReadStream(thumbCacheFile);
|
||||||
thumbStream.pipe(res);
|
thumbStream.pipe(res);
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
createThumbnail(cacheData, cacheContentFile, thumbCacheFile)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user