feat: TTFB 追踪记录与前端展示 + 缓存调度器代码整理

- CLI handler 记录上游请求 TTFB 并注入 proxy_info
- 前端请求时间线展示 TTFB 耗时
- 调度器提升局部 import 到模块顶部,提取 _affinity_hash/_merge_restriction_sets 辅助方法
- 修复缓存亲和性写入的缩进层级
- Python 版本回退至 3.13
This commit is contained in:
fawney19
2026-02-10 17:37:53 +08:00
parent 4276e7835c
commit 0c52341dec
5 changed files with 57 additions and 57 deletions

View File

@@ -932,7 +932,9 @@ class CliMessageHandlerBase(BaseMessageHandler):
payload=provider_payload,
timeout=request_timeout_sync,
)
_connect_start = time.monotonic()
resp = await http_client.post(**_pkw)
ctx.set_ttfb_ms(int((time.monotonic() - _connect_start) * 1000))
except (httpx.ConnectError, httpx.ConnectTimeout, httpx.TimeoutException) as e:
if envelope:
envelope.on_connection_error(base_url=ctx.selected_base_url, exc=e)
@@ -971,7 +973,9 @@ class CliMessageHandlerBase(BaseMessageHandler):
timeout=request_timeout_sync,
refresh_auth=True,
)
_connect_start = time.monotonic()
resp = await http_client.post(**_pkw)
ctx.set_ttfb_ms(int((time.monotonic() - _connect_start) * 1000))
ctx.status_code = resp.status_code
ctx.response_headers = dict(resp.headers)
if envelope:
@@ -1140,8 +1144,10 @@ class CliMessageHandlerBase(BaseMessageHandler):
else None
),
)
_connect_start = time.monotonic()
response_ctx = http_client.stream(**_skw)
stream_response = await response_ctx.__aenter__()
ctx.set_ttfb_ms(int((time.monotonic() - _connect_start) * 1000))
ctx.status_code = stream_response.status_code
ctx.response_headers = dict(stream_response.headers)

View File

@@ -112,7 +112,7 @@ class StreamContext:
perf_sampled: bool = False
perf_metrics: dict[str, Any] = field(default_factory=dict)
# 代理信息(用于 usage 记录和日志)
# 代理信息(用于 usage 记录和日志,含 ttfb_ms
proxy_info: dict[str, Any] | None = None
# 流式格式转换状态(跨 chunk 追踪)
@@ -267,6 +267,11 @@ class StreamContext:
"""检查是否因客户端断开连接而结束"""
return self.status_code == 499
def set_ttfb_ms(self, ms: int) -> None:
"""将首字节响应耗时TTFB注入到 proxy_info 中"""
if self.proxy_info is not None:
self.proxy_info["ttfb_ms"] = ms
def build_response_body(self, response_time_ms: int) -> dict[str, Any]:
"""
构建响应体元数据