Files
competition-website/app/lib/file_path_cache.js
WorkBuddy a303cf2d53 chore: 后端首次基线提交
运行必须源码:app/(controller/model/service/middleware/lib/utils/validate/router)、config/、database/(migrations/seeders/sql)、启动脚本、app/public/templates 模板。
已忽略运行非必须:node_modules/、logs/、run/、app/public 运行时上传数据、.env*、构建/缓存产物。
2026-08-17 12:25:42 +08:00

48 lines
1.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'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 };