mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
fix: 流式响应健壮性增强与候选排序稳定性修复
- test-model 接口优先使用流式请求,失败自动回退非流式 - CLI 流式处理在 StreamClosed/RemoteProtocolError 时 flush 残余 SSE 数据,捕获尾部 usage - 流未正常完成时兜底估算 tokens,避免 usage 记录为 0 - ProviderCandidate 添加 __lt__ 解决 tuple 排序 TypeError - sorted() 添加显式 key 参数避免隐式比较候选对象 - 异常日志改用 logger.opt(exception=e) 替代手动 traceback
This commit is contained in:
41
src/services/cache/aware_scheduler.py
vendored
41
src/services/cache/aware_scheduler.py
vendored
@@ -83,6 +83,43 @@ class ProviderCandidate:
|
||||
needs_conversion: bool = False # 是否需要格式转换
|
||||
provider_api_format: str = "" # Provider 端点实际格式(用于健康度/熔断 bucket)
|
||||
|
||||
def _stable_order_key(self) -> tuple[int, int, str, str, str]:
|
||||
"""
|
||||
为排序/优先队列提供稳定的比较键。
|
||||
|
||||
说明:
|
||||
- 运行时偶发会出现对 ProviderCandidate 做 tuple 排序/heap 排序的场景;
|
||||
当主键相同需要比较候选本身时,若候选不可比较会触发:
|
||||
TypeError: '<' not supported between instances of 'ProviderCandidate' and 'ProviderCandidate'
|
||||
- 这里提供一个与调度逻辑无关、但足够稳定且可比的兜底顺序。
|
||||
"""
|
||||
provider_priority_raw = getattr(self.provider, "provider_priority", None)
|
||||
internal_priority_raw = getattr(self.key, "internal_priority", None)
|
||||
|
||||
try:
|
||||
provider_priority = (
|
||||
int(provider_priority_raw) if provider_priority_raw is not None else 999999
|
||||
)
|
||||
except Exception:
|
||||
provider_priority = 999999
|
||||
|
||||
try:
|
||||
internal_priority = (
|
||||
int(internal_priority_raw) if internal_priority_raw is not None else 999999
|
||||
)
|
||||
except Exception:
|
||||
internal_priority = 999999
|
||||
|
||||
provider_id = str(getattr(self.provider, "id", "") or "")
|
||||
endpoint_id = str(getattr(self.endpoint, "id", "") or "")
|
||||
key_id = str(getattr(self.key, "id", "") or "")
|
||||
return (provider_priority, internal_priority, provider_id, endpoint_id, key_id)
|
||||
|
||||
def __lt__(self, other: object) -> bool:
|
||||
if not isinstance(other, ProviderCandidate):
|
||||
return NotImplemented
|
||||
return self._stable_order_key() < other._stable_order_key()
|
||||
|
||||
|
||||
@dataclass
|
||||
class ConcurrencySnapshot:
|
||||
@@ -1585,7 +1622,7 @@ class CacheAwareScheduler:
|
||||
scored_candidates.append((hash_value, candidate))
|
||||
|
||||
# 按哈希值排序
|
||||
sorted_group = [c for _, c in sorted(scored_candidates)]
|
||||
sorted_group = [c for _, c in sorted(scored_candidates, key=lambda x: x[0])]
|
||||
result.extend(sorted_group)
|
||||
else:
|
||||
# 单个候选或没有 affinity_key,按次要排序条件排序
|
||||
@@ -1706,7 +1743,7 @@ class CacheAwareScheduler:
|
||||
key_scores.append((hash_value, key))
|
||||
|
||||
# 按哈希值排序
|
||||
sorted_group = [key for _, key in sorted(key_scores)]
|
||||
sorted_group = [key for _, key in sorted(key_scores, key=lambda x: x[0])]
|
||||
result.extend(sorted_group)
|
||||
else:
|
||||
# 没有 affinity_key 时按 ID 排序保持稳定性
|
||||
|
||||
Reference in New Issue
Block a user