refactor: 统一任务框架 Phase 3 - 用 TaskService/FailoverEngine 替代 FallbackOrchestrator

核心重构:
- 移除 FallbackOrchestrator,用 TaskService + FailoverEngine 替代
- TaskService 作为统一入口,支持 SYNC/ASYNC 两种任务模式
- FailoverEngine 实现候选遍历、重试、故障转移逻辑
- 新增 AttemptFunc/AttemptResult 协议,统一尝试结果表示

功能改进:
- 流式响应首字节探测(30s 超时,空流触发故障转移)
- 流式取消归因优化(区分客户端断连 vs 服务端中断)
- 新增 OpenAI Sora 视频取消路由 POST /v1/videos/{task_id}/cancel
- OpenAI 流式请求自动添加 stream_options.include_usage

代码规范:
- 修复 loguru 日志格式(%s → {})
- 新增 FORMAT_CONVERSION_ENABLED 环境变量说明

测试覆盖:
- test_failover_engine.py: FailoverEngine 单元测试
- test_task_service_async_execute.py: TaskService ASYNC 模式测试
- test_video_cancel_e2e.py: 视频取消端到端测试
This commit is contained in:
fawney19
2026-02-02 21:16:28 +08:00
parent ebe1a8d3e3
commit ed68aebfb0
53 changed files with 3966 additions and 2256 deletions

View File

@@ -270,7 +270,7 @@ class AdminUpdateEndpointKeyAdapter(AdminApiAdapter):
update_data["rpm_limit"] = self.key_data.rpm_limit
if self.key_data.rpm_limit is None:
update_data["learned_rpm_limit"] = None
logger.info("Key %s 切换为自适应 RPM 模式", self.key_id)
logger.info("Key {} 切换为自适应 RPM 模式", self.key_id)
# 统一处理 allowed_models空列表 -> None表示不限制
if "allowed_models" in update_data:
@@ -305,7 +305,7 @@ class AdminUpdateEndpointKeyAdapter(AdminApiAdapter):
# 处理 auto_fetch_models 的开启和关闭
if not auto_fetch_enabled_before and auto_fetch_enabled_after:
# 刚刚开启了 auto_fetch_models同步执行模型获取
logger.info("[AUTO_FETCH] Key %s 开启自动获取模型,同步执行模型获取", self.key_id)
logger.info("[AUTO_FETCH] Key {} 开启自动获取模型,同步执行模型获取", self.key_id)
try:
from src.services.model.fetch_scheduler import get_model_fetch_scheduler
@@ -321,14 +321,14 @@ class AdminUpdateEndpointKeyAdapter(AdminApiAdapter):
if locked:
key.allowed_models = locked
logger.info(
"[AUTO_FETCH] Key %s 关闭自动获取模型,保留 %d 个锁定模型",
"[AUTO_FETCH] Key {} 关闭自动获取模型,保留 {} 个锁定模型",
self.key_id,
len(locked),
)
else:
key.allowed_models = None
logger.info(
"[AUTO_FETCH] Key %s 关闭自动获取模型,无锁定模型,清空 allowed_models",
"[AUTO_FETCH] Key {} 关闭自动获取模型,无锁定模型,清空 allowed_models",
self.key_id,
)
db.commit()
@@ -344,7 +344,7 @@ class AdminUpdateEndpointKeyAdapter(AdminApiAdapter):
if patterns_changed:
# 过滤规则变更,重新应用过滤(使用缓存的上游模型数据)
logger.info(
"[AUTO_FETCH] Key %s 过滤规则变更,重新应用过滤",
"[AUTO_FETCH] Key {} 过滤规则变更,重新应用过滤",
self.key_id,
)
try:
@@ -373,7 +373,7 @@ class AdminUpdateEndpointKeyAdapter(AdminApiAdapter):
# allowed_models 未变化时,仍需清除 /v1/models 缓存is_active、api_formats 变更会影响模型可用性)
await invalidate_models_list_cache()
logger.info("[OK] 更新 Key: ID=%s, Updates=%s", self.key_id, list(update_data.keys()))
logger.info("[OK] 更新 Key: ID={}, Updates={}", self.key_id, list(update_data.keys()))
return _build_key_response(key)
@@ -794,7 +794,7 @@ class AdminCreateProviderKeyAdapter(AdminApiAdapter):
# 如果开启了 auto_fetch_models同步执行模型获取
if self.key_data.auto_fetch_models:
logger.info("[AUTO_FETCH] 新 Key %s 开启自动获取模型,同步执行模型获取", new_key.id)
logger.info("[AUTO_FETCH] 新 Key {} 开启自动获取模型,同步执行模型获取", new_key.id)
try:
from src.services.model.fetch_scheduler import get_model_fetch_scheduler