gcli2api / internal /pool /realm.go
a3216's picture
chore: 同步到上游 1.12.0-panel + 凭证同步/独立启动器/保活
6d60378 verified
Raw History Blame Contribute Delete
2.87 kB
// 分池选号域:按 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
}