mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 09:20:22 +08:00
- 新增 multi_score 调度模式,支持 LRU/延迟/健康度/剩余额度多维加权评分 - 新增调度预设维度系统(free_team_first, quota_balanced, recent_refresh, single_account),支持有序对象列表配置格式并兼容旧字符串列表 - 新增 account_state 模块,统一账号封禁/受限检测逻辑,替代分散在 routes 中的判断代码 - 新增 health_cache 模块和 latency 采样(redis_ops.record_latency / batch_get_latency_avgs) - RequestDispatcher 返回 ttfb_ms,PoolManager.on_request_success 记录延迟样本 - 前端:PoolConfigDialog 替换为 PoolSchedulingDialog,支持预设维度可视化配置;号池管理页增加调度模式标签与账号异常 Badge 显示 - 提取前端 accountBlock 工具函数,ProviderDetailDrawer 复用统一判断 - scheduling_dimensions 增加 account_state 和 latency 维度评估 - 补充 account_state、health_cache、multi_score 策略、preset 维度、redis latency 等测试
59 lines
2.0 KiB
Python
59 lines
2.0 KiB
Python
"""Tests for pool health cache helpers."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from types import SimpleNamespace
|
|
|
|
from src.services.provider.pool import health_cache
|
|
|
|
|
|
def setup_function() -> None:
|
|
health_cache._clear_cache_for_tests()
|
|
|
|
|
|
def teardown_function() -> None:
|
|
health_cache._clear_cache_for_tests()
|
|
|
|
|
|
def test_aggregate_health_score_uses_lowest_format_score() -> None:
|
|
score = health_cache.aggregate_health_score(
|
|
{
|
|
"openai:chat": {"health_score": 0.92},
|
|
"openai:responses": {"health_score": 0.61},
|
|
}
|
|
)
|
|
assert score == 0.61
|
|
|
|
|
|
def test_get_health_scores_uses_cache_for_same_provider() -> None:
|
|
key = SimpleNamespace(id="k1", health_by_format={"f1": {"health_score": 0.7}})
|
|
first = health_cache.get_health_scores("p1", [key])
|
|
assert first["k1"] == 0.7
|
|
|
|
key.health_by_format = {"f1": {"health_score": 0.2}}
|
|
second = health_cache.get_health_scores("p1", [key])
|
|
assert second["k1"] == 0.7
|
|
|
|
|
|
def test_get_health_scores_merges_missing_keys_into_cache() -> None:
|
|
k1 = SimpleNamespace(id="k1", health_by_format={"f1": {"health_score": 0.7}})
|
|
first = health_cache.get_health_scores("p1", [k1])
|
|
assert first == {"k1": 0.7}
|
|
|
|
# Request with a new key k2 -- k1 should come from cache, k2 freshly computed
|
|
k1_stale = SimpleNamespace(id="k1", health_by_format={"f1": {"health_score": 0.1}})
|
|
k2 = SimpleNamespace(id="k2", health_by_format={"f1": {"health_score": 0.5}})
|
|
second = health_cache.get_health_scores("p1", [k1_stale, k2])
|
|
assert second["k1"] == 0.7 # cached, not recomputed
|
|
assert second["k2"] == 0.5 # freshly computed
|
|
|
|
|
|
def test_invalidate_provider_health_scores_clears_cache_entry() -> None:
|
|
key = SimpleNamespace(id="k1", health_by_format={"f1": {"health_score": 0.8}})
|
|
_ = health_cache.get_health_scores("p1", [key])
|
|
health_cache.invalidate_provider_health_scores("p1")
|
|
|
|
key.health_by_format = {"f1": {"health_score": 0.3}}
|
|
refreshed = health_cache.get_health_scores("p1", [key])
|
|
assert refreshed["k1"] == 0.3
|