fix(daily-volume): 历史快照的 partial 自动修正 + 三个回归测试
=== 现象 === 仓库里 6 条快照 partial 全是 true(10-27 到 10-30),前端把昨天的柱子 也画成虚线空心,看着像"每天都在采样中"。 === 根因 === 早期实现把两件事都塞进 partial:「今天还没过完」和「起点超出 24h」。 10-27/10-28 的数据现在已经被 retention 删掉、永远不会再被抓一次, 所以这两条错误标记会永久留在库里。 === 修法 === prune 里加幂等修正:过去的天,只有快照是**在那天结束之后**才抓的 (说明抓到的是完整一天)才改成 partial=false;当天中途抓的继续保持 partial (那时确实只有半天,不能伪装成完整数据)。 === 测试(3/3 PASS)=== TestPruneDailyVolumeNormalizesPartialAndDropsExpired · 昨天结束之后抓的 → partial=false · 前天中途抓的 → 保持 partial=true · 今天 → 保持 partial=true · 超留存期 → 被清理 · 条数不被清理流程清空 TestUpsertVolumeSnapshotKeepsEntries 刷新体积不清空已抓到的条数 TestGetDailyVolumeHistoryReturnsAllDaysWithMissing 始终返回 days 个点,缺的标 Missing 不伪造 0 go vet ./services/ ./models/ 干净;go test ./services/ 全绿。
This commit is contained in:
1 parent
b7de337c9e
commit
63dd491c5b
2 files changed
+164
-3
No files matched your search
@@ -301,24 +301,49 @@ func CaptureRecentDailyVolumes() {
|
||||
pruneDailyVolumeSnapshots()
|
||||
}
|
||||
|
||||
// pruneDailyVolumeSnapshots 丢弃超过保留期的历史。
|
||||
// pruneDailyVolumeSnapshots 丢弃超过保留期的历史,并修正历史遗留的 partial 标记。
|
||||
func pruneDailyVolumeSnapshots() {
|
||||
db := repository.GetDB()
|
||||
if db == nil {
|
||||
return
|
||||
}
|
||||
cutoff := dateKey(time.Now().AddDate(0, 0, -dailyVolumeRetentionDays))
|
||||
today := dateKey(time.Now())
|
||||
db.Lock()
|
||||
defer db.Unlock()
|
||||
changed := false
|
||||
kept := make([]models.DailyVolumeSnapshot, 0, len(db.DailyVolumeSnapshots))
|
||||
for _, snap := range db.DailyVolumeSnapshots {
|
||||
if snap.Date >= cutoff {
|
||||
kept = append(kept, snap)
|
||||
if snap.Date < cutoff {
|
||||
continue
|
||||
}
|
||||
kept = append(kept, snap)
|
||||
}
|
||||
if len(kept) != len(db.DailyVolumeSnapshots) {
|
||||
log.Printf("[daily-volume] 清理过期快照 %d 条", len(db.DailyVolumeSnapshots)-len(kept))
|
||||
db.DailyVolumeSnapshots = kept
|
||||
changed = true
|
||||
}
|
||||
|
||||
// 历史遗留修正:**过去的天不可能"还在进行中"**。
|
||||
// 早期版本把「起点超出 24h」也当成 partial,于是昨天/前天的柱子一直是虚线空心,
|
||||
// 看起来像"每天都在采样中"。只有当快照是在那天**结束之后**才抓的
|
||||
// (说明抓的是完整一天)才改成完整;当天中途抓到的继续保持 partial —— 那时确实只有半天。
|
||||
for i := range db.DailyVolumeSnapshots {
|
||||
snap := &db.DailyVolumeSnapshots[i]
|
||||
if !snap.Partial || snap.Date >= today {
|
||||
continue
|
||||
}
|
||||
day, err := time.ParseInLocation("2006-01-02", snap.Date, time.Local)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if _, dayEnd := dayRange(day); snap.CapturedAt.UnixNano() >= dayEnd {
|
||||
snap.Partial = false
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
if changed {
|
||||
db.RequestSave()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user