fix: 重算到期时间不抵消失败退避,重置日前统计只计有生效套餐的卡
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled

- 上次检查时间只在查询成功时更新,按"上次检查 + 新间隔"会把失败或限流延后的卡拉到立即执行;
  过期或从未检查时候选改为"现在 + 新间隔",只提前排队超过一个新间隔的成员
- 重置日前加密统计只记录有生效套餐的卡,与"有生效套餐但窗口内未查到"口径一致
This commit is contained in:
邹进
2026-10-24 17:28:18 +09:00
parent 98017ac053
commit ec5c1996a7
3 changed files with 23 additions and 5 deletions

View File

@@ -107,6 +107,10 @@ func (m *PollingConfigManager) RecordPreResetCheck(ctx context.Context, card *mo
if now.Before(reset.Add(-time.Duration(*cfg.PreResetWindow) * time.Second)) {
return
}
// 只统计有生效套餐的卡,与统计接口"有生效套餐但窗口内未查到"的口径一致。
if facts := m.TierFactsOf(card); !facts.Known || facts.PackageState != constants.PollingPackageStateActive {
return
}
date := reset.Format("20060102")
member := strconv.FormatUint(uint64(card.ID), 10)
minutes := int(reset.Sub(now).Minutes())

View File

@@ -104,7 +104,7 @@ func (r *DueRecalculator) recalculateBatch(ctx context.Context, cards []*model.I
shardID := int(card.ID) % r.queueMgr.shardCount
member := strconv.FormatUint(uint64(card.ID), 10)
for taskType, info := range r.configMgr.MergedTaskIntervals(card) {
due := calculateNextCheckTime(lastCheckAtByTaskType(card, taskType), info.Interval, now)
due := recalculatedDue(lastCheckAtByTaskType(card, taskType), info.Interval, now)
if windowDue := r.configMgr.NextCheckAt(ctx, card, taskType, info, now); windowDue.Before(due) && windowDue.After(now) {
due = windowDue
}
@@ -127,3 +127,17 @@ func (r *DueRecalculator) recalculateBatch(ctx context.Context, cards []*model.I
}
return advanced, nil
}
// recalculatedDue 返回重算的候选到期时间。上次检查时间只在查询成功时更新,查询失败或被限流延后的卡按
// "上次检查 + 新间隔"会算成已过期;此时候选改为"现在 + 新间隔",只提前排队超过一个新间隔的成员,
// 不抵消失败退避与限流延后,也避免重算后集中触发调用。
func recalculatedDue(lastCheckAt *time.Time, intervalSeconds int, now time.Time) time.Time {
interval := time.Duration(intervalSeconds) * time.Second
if lastCheckAt == nil {
return now.Add(interval)
}
if due := lastCheckAt.Add(interval); due.After(now) {
return due
}
return now.Add(interval)
}

View File

@@ -46,10 +46,10 @@
## 8. 测试环境验证(自动化测试为 N/A,按 ENG-TEST-001)
- [ ] 8.1 现有配置在升级后各卡最终间隔不变(用匹配预览抽查)。
- [ ] 8.2 间隔 `0` 停止继承、空值继承、相同优先级按 ID 稳定。
- [ ] 8.3 无套餐已销售、在库层卡状态为空或 0 时保存被拒;未匹配告警出现。
- [ ] 8.4 整体排序后匹配结果按新顺序;重算到期时间只提前不推后。
- [x] 8.1 现有配置在升级后各卡最终间隔不变(用匹配预览抽查)。(2026-10-24:唯一启用配置 29,28 张卡均命中,间隔与来源正确)
- [x] 8.2 间隔 `0` 停止继承、空值继承、相同优先级按 ID 稳定。(草稿预演通过)
- [x] 8.3 无套餐已销售、在库层卡状态为空或 0 时保存被拒;未匹配告警出现。(保存被拒已验证;未匹配告警按统计接口 unmatched_* 观察,当前为 0)
- [x] 8.4 整体排序后匹配结果按新顺序;重算到期时间只提前不推后。(重排与失败回滚通过;发现失败/限流延后的卡被重算拉到立即执行,已改为过期时候选取"现在 + 新间隔")
- [ ] 8.5 重置日前窗口:最后一次查询落在"重置时刻 − 收尾提前量",越过后恢复正常间隔。
- [ ] 8.6 二次销售卡购买即生效:先结算再激活,新套餐不承担上一用户本月用量;结算不产生停机。
- [ ] 8.7 构造结算慢返回且另一入口先激活:激活前用量只记已结算。