fix: 缓存击穿/play竞态/onUnload泄漏/清除数据UI/统计NaN
- leaderboard 云函数: _fetchLatestByOpenid 加 in-flight promise,并发请求复用同一次扫描,防缓存击穿 - voice: play 加序列号,丢弃过期播放,避免旧语音截断新语音 - timer: onUnload 补取消 _completionCountUp,系统返回手势不再泄漏动画定时器 - settings: 清除数据 setData 补 voiceGender/vibrateIntensity 重置,避免 UI 与存储不一致 - storage: getTotalStats 对 r.duration 防御(Number||0),避免脏数据产生 NaN 传染 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,7 @@ const TZ_OFFSET_MS = 8 * 60 * 60 * 1000
|
||||
// across instances, which is fine - the board needn't be real-time.
|
||||
const CACHE_TTL = 60 * 1000
|
||||
let _docsCache = null // { latestByOpenid: Map, ts }
|
||||
let _docsCachePromise = null // in-flight 扫描 promise,防缓存击穿
|
||||
|
||||
const tsOf = (d) => {
|
||||
if (!d.updatedAt) return 0
|
||||
@@ -40,6 +41,9 @@ const _fetchLatestByOpenid = async () => {
|
||||
if (_docsCache && (Date.now() - _docsCache.ts) < CACHE_TTL) {
|
||||
return _docsCache.latestByOpenid
|
||||
}
|
||||
// 缓存过期:复用 in-flight promise,避免并发请求各自全表扫描(缓存击穿)
|
||||
if (_docsCachePromise) return _docsCachePromise
|
||||
_docsCachePromise = (async () => {
|
||||
const latestByOpenid = new Map()
|
||||
// Exclude accounts that haven't synced in 90+ days to bound the scan.
|
||||
// Docs without an updatedAt field (pre-fix legacy) are included as well.
|
||||
@@ -66,6 +70,8 @@ const _fetchLatestByOpenid = async () => {
|
||||
}
|
||||
_docsCache = { latestByOpenid, ts: Date.now() }
|
||||
return latestByOpenid
|
||||
})()
|
||||
try { return await _docsCachePromise } finally { _docsCachePromise = null }
|
||||
}
|
||||
|
||||
exports.main = async (event) => {
|
||||
|
||||
Reference in New Issue
Block a user