iboard/server/apizero/cache.js
2026-08-07 14:36:57 +08:00

47 lines
1.4 KiB
JavaScript

// apizero 接口的文件缓存
// - 按 key 存 JSON 到磁盘: <APIZERO_CACHE_DIR>/<key>.json
// - 存在性检查: 文件在即视为有效 (用户要求: "同一个年份只要存在就不再调用接口")
// - 不做 TTL: 用户没要求, 也避免误命中过期数据
//
// 环境变量:
// APIZERO_CACHE_DIR 缓存目录 (默认 <cwd>/cache/apizero)
//
// 未来若要加 TTL / DB 后端, 替换本文件即可, 上层调用方不变.
import fs from 'node:fs'
import path from 'node:path'
function dir() {
return process.env.APIZERO_CACHE_DIR
? path.resolve(process.env.APIZERO_CACHE_DIR)
: path.resolve(process.cwd(), 'cache', 'apizero')
}
// 读缓存, 不存在返回 null
export function read(key) {
const p = path.join(dir(), key + '.json')
if (!fs.existsSync(p)) return null
try {
const raw = fs.readFileSync(p, 'utf8')
return JSON.parse(raw)
} catch (e) {
console.warn(`[apizero-cache] 读 ${key} 失败, 忽略:`, e.message)
return null
}
}
// 写缓存 (原子: 先写 .tmp 再 rename)
export function write(key, data) {
const d = dir()
fs.mkdirSync(d, { recursive: true })
const final = path.join(d, key + '.json')
const tmp = final + '.tmp.' + process.pid
fs.writeFileSync(tmp, JSON.stringify(data), 'utf8')
fs.renameSync(tmp, final)
return final
}
// 存在性检查
export function has(key) {
return fs.existsSync(path.join(dir(), key + '.json'))
}