File size: 2,865 Bytes
6d60378 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | // 分池选号域:按 realm(cn/global)过滤选号与可用集合。realm=="" 退化为现状。
package pool
import (
"sort"
"time"
)
// expiringVirtualSlots 快过期账号在新会话候选集中的虚拟实例权重。
// 3:1 是温和偏好,不是固定比例:账号组成变化会自然改变最终占比。
const expiringVirtualSlots = 3
// AvailableUIDsForRealm 同 AvailableUIDs,但仅返回 Realm()==realm 的账号。
// realm=="" 退化为 AvailableUIDs(现状语义)。
func (p *Pool) AvailableUIDsForRealm(realm string) []string {
p.mu.RLock()
defer p.mu.RUnlock()
now := time.Now()
uids := make([]string, 0, len(p.byUID))
for uid, e := range p.byUID {
if realm != "" && e.a.Realm() != realm {
continue
}
if !e.healthy(now) {
continue
}
if p.inFlightFull(e) {
continue
}
uids = append(uids, uid)
}
sort.Strings(uids)
return uids
}
// WeightedAvailableUIDsForModelRealm 返回带虚拟实例权重的可用账号列表。
//
// 普通账号出现 1 次;有效快过期账号出现 expiringVirtualSlots 次。调用方继续按
// 原有序列表哈希,即可让新会话对快过期账号形成温和偏好。重复项按 UID 排序后
// 展开,保证同一账号拓扑下不同进程得到一致列表。
//
// 该方法是现有 AvailableUIDsForModelRealm 的增量入口,不改变旧方法语义,也不
// 修改配置、状态或 Redis schema。prefer_expiring=false 时退化为逐账号一次。
func (p *Pool) WeightedAvailableUIDsForModelRealm(model, realm string) []string {
p.mu.RLock()
defer p.mu.RUnlock()
now := time.Now()
uids := make([]string, 0, len(p.byUID))
for uid, e := range p.byUID {
if realm != "" && e.a.Realm() != realm {
continue
}
if !e.healthyForModel(now, model) {
continue
}
if p.inFlightFull(e) {
continue
}
uids = append(uids, uid)
}
sort.Strings(uids)
out := make([]string, 0, len(uids))
for _, uid := range uids {
slots := 1
if p.preferExpiring {
if e := p.byUID[uid]; expiringNow(e, now) {
slots = expiringVirtualSlots
}
}
for i := 0; i < slots; i++ {
out = append(out, uid)
}
}
return out
}
// AvailableUIDsForModelRealm 同 AvailableUIDsForModel,但仅返回 Realm()==realm 的账号
// (6004 模型豁免照常生效)。realm=="" 退化为 AvailableUIDsForModel。
func (p *Pool) AvailableUIDsForModelRealm(model, realm string) []string {
p.mu.RLock()
defer p.mu.RUnlock()
now := time.Now()
uids := make([]string, 0, len(p.byUID))
for uid, e := range p.byUID {
if realm != "" && e.a.Realm() != realm {
continue
}
if !e.healthyForModel(now, model) {
continue
}
if p.inFlightFull(e) {
continue
}
uids = append(uids, uid)
}
sort.Strings(uids)
return uids
}
|