Files
competition-website/app/lib/file_path_cache.js

48 lines
1.6 KiB
JavaScript
Raw Normal View History

'use strict';
/**
* 下载前 file_path 短缓存(进程内,默认 30s)。
*
* 收益:高并发下载同一文件时,避免每次请求都回查 DB 取 file_path / file_name。
*
* 取舍(任务 #23 已确认):文件替换 / 删除后,≤ TTL 内可能命中旧路径。
* - 下游 _sendFile 仍按实际文件做 fs.existsSync 校验,旧路径不存在 → 404,不会吐错误内容;
* - 被替换文件的旧路径在 TTL 内至多吐出旧版本一小段时间(非安全敏感、非实时场景,可接受)。
* - 因此本缓存为「只读穿透 + TTL 自愈」,不强制接入上传/删除失效,
* 以最小化改动面与回归风险;如需更强一致可后续在上传/删除成功处调用 invalidate()。
*
* 键约定:调用方自行拼装唯一 key,如 `word:${group}:${id}` / `sub:${group}:${id}`。
*/
const TTL_MS = 30 * 1000;
const store = new Map(); // key -> { filePath, fileName, expire }
function _now() {
return Date.now();
}
function getFull(key) {
if (!key) return null;
const hit = store.get(key);
if (!hit) return null;
if (hit.expire < _now()) {
store.delete(key);
return null;
}
return { filePath: hit.filePath, fileName: hit.fileName };
}
function setFull(key, filePath, fileName) {
if (!key || filePath == null || filePath === '') return;
store.set(key, {
filePath: String(filePath),
fileName: fileName == null ? '' : String(fileName),
expire: _now() + TTL_MS,
});
}
function invalidate(key) {
if (key) store.delete(key);
}
module.exports = { getFull, setFull, invalidate, TTL_MS };