运行必须源码:app/(controller/model/service/middleware/lib/utils/validate/router)、config/、database/(migrations/seeders/sql)、启动脚本、app/public/templates 模板。 已忽略运行非必须:node_modules/、logs/、run/、app/public 运行时上传数据、.env*、构建/缓存产物。
48 lines
1.6 KiB
JavaScript
48 lines
1.6 KiB
JavaScript
'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 };
|