fix: 重算到期时间不抵消失败退避,重置日前统计只计有生效套餐的卡
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
- 上次检查时间只在查询成功时更新,按"上次检查 + 新间隔"会把失败或限流延后的卡拉到立即执行; 过期或从未检查时候选改为"现在 + 新间隔",只提前排队超过一个新间隔的成员 - 重置日前加密统计只记录有生效套餐的卡,与"有生效套餐但窗口内未查到"口径一致
This commit is contained in:
@@ -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())
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 构造结算慢返回且另一入口先激活:激活前用量只记已结算。
|
||||
|
||||
Reference in New Issue
Block a user