mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
feat(pool): 新增调度维度、互斥组机制、健康策略扩展与配额刷新增强
- 新增 priority_first/health_first/latency_first/cost_first 四个调度维度 - 引入 mutex_group 互斥组机制,lru 与 single_account 归入 distribution_mode - 维度 compute_metric 签名扩展 context 参数,支持获取 cost_totals 等上下文 - 各维度增加 evidence_hint 字段描述评分依据 - 健康策略扩展 408/409/423/425/5xx 瞬态状态码冷却,403 按 body 分级冷却 - Codex 配额刷新增强 401/402/403 错误处理,402 生成 fallback 元数据 - 前端号池管理支持账号优先级内联编辑与互斥维度切换 UI - 列表排序改为 internal_priority + created_at,移除 sticky_counts 查询
This commit is contained in:
@@ -160,6 +160,13 @@ _COOLDOWN_REASON_LABELS: dict[str, str] = {
|
||||
"auth_failed_401": "401 认证失败",
|
||||
"payment_required_402": "402 欠费",
|
||||
"server_error_500": "500 错误",
|
||||
"request_timeout_408": "408 超时",
|
||||
"conflict_409": "409 冲突",
|
||||
"locked_423": "423 锁定",
|
||||
"too_early_425": "425 Too Early",
|
||||
"bad_gateway_502": "502 网关错误",
|
||||
"service_unavailable_503": "503 服务不可用",
|
||||
"gateway_timeout_504": "504 网关超时",
|
||||
}
|
||||
|
||||
|
||||
@@ -607,6 +614,8 @@ class AdminListSchedulingPresetsAdapter(AdminApiAdapter):
|
||||
providers=[],
|
||||
modes=None,
|
||||
default_mode=None,
|
||||
mutex_group="distribution_mode",
|
||||
evidence_hint="依据 LRU 时间戳(最近未使用优先)",
|
||||
)
|
||||
]
|
||||
|
||||
@@ -625,6 +634,8 @@ class AdminListSchedulingPresetsAdapter(AdminApiAdapter):
|
||||
providers=list(meta.providers),
|
||||
modes=modes,
|
||||
default_mode=meta.default_mode,
|
||||
mutex_group=meta.mutex_group,
|
||||
evidence_hint=meta.evidence_hint,
|
||||
)
|
||||
)
|
||||
return items
|
||||
@@ -766,7 +777,14 @@ class AdminListPoolKeysAdapter(AdminApiAdapter):
|
||||
# Limit scan range to avoid loading the entire table into memory.
|
||||
if self.status == "cooldown":
|
||||
_max_scan = 2000
|
||||
all_keys = q.order_by(ProviderAPIKey.created_at.desc()).limit(_max_scan).all()
|
||||
all_keys = (
|
||||
q.order_by(
|
||||
ProviderAPIKey.internal_priority.asc(),
|
||||
ProviderAPIKey.created_at.asc(),
|
||||
)
|
||||
.limit(_max_scan)
|
||||
.all()
|
||||
)
|
||||
key_ids = [str(k.id) for k in all_keys]
|
||||
cooldowns = await pool_redis.batch_get_cooldowns(pid, key_ids) if key_ids else {}
|
||||
all_keys = [k for k in all_keys if cooldowns.get(str(k.id)) is not None]
|
||||
@@ -777,7 +795,10 @@ class AdminListPoolKeysAdapter(AdminApiAdapter):
|
||||
total = int(q.with_entities(func.count(ProviderAPIKey.id)).scalar() or 0)
|
||||
offset = (self.page - 1) * self.page_size
|
||||
keys = (
|
||||
q.order_by(ProviderAPIKey.created_at.desc())
|
||||
q.order_by(
|
||||
ProviderAPIKey.internal_priority.asc(),
|
||||
ProviderAPIKey.created_at.asc(),
|
||||
)
|
||||
.offset(offset)
|
||||
.limit(self.page_size)
|
||||
.all()
|
||||
@@ -785,6 +806,9 @@ class AdminListPoolKeysAdapter(AdminApiAdapter):
|
||||
|
||||
# Batch fetch Redis state (parallel where possible)
|
||||
key_ids = [str(k.id) for k in keys]
|
||||
# Sticky session counts are no longer fetched from Redis to reduce
|
||||
# round-trips; the field is kept at 0 for schema compatibility.
|
||||
sticky_counts: dict[str, int] = {kid: 0 for kid in key_ids}
|
||||
if key_ids:
|
||||
_lru_coro = (
|
||||
pool_redis.get_lru_scores(pid, key_ids)
|
||||
@@ -807,18 +831,15 @@ class AdminListPoolKeysAdapter(AdminApiAdapter):
|
||||
lru_scores,
|
||||
latency_avgs,
|
||||
cost_totals,
|
||||
sticky_counts,
|
||||
) = await asyncio.gather(
|
||||
pool_redis.batch_get_cooldowns(pid, key_ids),
|
||||
pool_redis.batch_get_cooldown_ttls(pid, key_ids),
|
||||
_lru_coro,
|
||||
_latency_coro,
|
||||
_cost_coro,
|
||||
pool_redis.batch_get_key_sticky_counts(pid, key_ids),
|
||||
)
|
||||
else:
|
||||
cooldowns, cooldown_ttls, lru_scores, latency_avgs, cost_totals, sticky_counts = (
|
||||
{},
|
||||
cooldowns, cooldown_ttls, lru_scores, latency_avgs, cost_totals = (
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
|
||||
@@ -46,6 +46,8 @@ class PresetDimensionMetaResponse(BaseModel):
|
||||
providers: list[str] = Field(default_factory=list)
|
||||
modes: list[PresetModeMetaResponse] | None = None
|
||||
default_mode: str | None = None
|
||||
mutex_group: str | None = None
|
||||
evidence_hint: str | None = None
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user