fix(notify): 汇总模式按消息计量限流,批次大小不再被每轮请求预算掐死
令牌桶的额度此前被同时当成两个量纲用:对实时模式它是「发几条消息」, 对汇总模式却被直接当成「一批装几条漏洞」传给 ClaimDigestBatch。 notifyMaxSendsPerChannelPerTick(=5)是由租约时长倒推的 HTTP 请求预算, 而一个汇总批次只发一次请求,两者本不该相乘。稳态下更糟:rate_per_min=20 的渠道在 3 秒的 tick 里只补得到 1 个令牌,于是每条汇总消息只装 1 个漏洞, 头部还写着「近 30 分钟新增 1 个漏洞」——digest 退化成带汇总文案的实时推送, MaxDigestBatchSize(500) 永不可达。 改为统一按**消息条数**计量:一批漏洞合成一条消息、消耗一个令牌, rate_per_min 对 digest 依然生效(每分钟最多这么多条汇总消息), 而批次大小只受 MaxDigestBatchSize 这个内存上界约束。 ClaimDigestBatch 原先的注释声称「单批同时受限流额度与内存上界约束」, 那正是本问题的来源——限流额度本不该充当批次大小。注释一并改掉, 免得下次又按「rate_per_min 对 digest 不生效」把它改回去。 顺带让 takeTokens 接受 want 上限:原先整桶抽空后才由调用方截断, 多出来的令牌(飞书默认 100/min 时是 95 个)直接丢弃,渠道这一轮 没有待发投递时也照扣,注释声称的突发容量在任何情况下都做不到。 决策收在 digestTickPlan 里由新增用例直接钉住。现有端到端用例都手动给 stepDigest 传一个够大的 limit,绕过了 step 里的额度计算,所以覆盖不到这里。
This commit is contained in:
1 parent
f2f35ebc2e
commit
93c1d39df3
3 files changed
+123
-26
No files matched your search
@@ -171,9 +171,15 @@ func (d *DB) ClaimDigestBatch(ctx context.Context, channelID int64, limit int, l
|
||||
if limit <= 0 {
|
||||
return nil, nil
|
||||
}
|
||||
// 单批同时受两个上界约束:调用方的限流额度(本轮还能发几条)与内存上界
|
||||
// MaxDigestBatchSize。此前只用了后者,于是 digest 渠道的 rate_per_min
|
||||
// 完全不生效——令牌被 takeTokens 扣掉却没人用,等于白扣。
|
||||
// limit 是**内存上界**,调用方传 MaxDigestBatchSize;这里再夹一道,
|
||||
// 防止调用方传进一个更大的值。
|
||||
//
|
||||
// 刻意不接受「限流额度」充当批次大小:限流的单位是消息条数——一个批次只发
|
||||
// 一条消息、消耗一个令牌,由 server 层的 takeTokens 扣除——与「一批装几条
|
||||
// 漏洞」是两个不同的量纲。曾经为了让 rate_per_min 对 digest 生效而把每轮
|
||||
// 请求预算传进来当批次大小,结果 rate=20/min 的渠道每批只装 1 条漏洞,
|
||||
// digest 退化成带汇总文案的实时推送。要改限流请改 takeTokens 的 want,
|
||||
// 不要动这里。
|
||||
if limit > MaxDigestBatchSize {
|
||||
limit = MaxDigestBatchSize
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user