mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-05 23:47:41 +08:00
refactor: introduce typed host runtime
This commit is contained in:
@@ -219,7 +219,8 @@ sequenceDiagram
|
||||
Life->>Init: get_engine() / get_global_async_engine() 预热 + fail-fast
|
||||
Life->>Init: check_connection_budget() 连接预算核算
|
||||
Life->>Init: init_routers(app) 注册 API 路由
|
||||
Life->>Init: init_modules() 发现并初始化模块
|
||||
Life->>Init: init_modules() 发现并初始化模块,返回 HostRuntime
|
||||
Life->>FastAPI: app.state.host_runtime = HostRuntime
|
||||
Life->>Init: init_plugins() / init_scheduler() / init_monitor()
|
||||
Life->>Init: init_command() / init_workflow()
|
||||
Life->>Init: replay_pending_transfers()(后台回放未整理文件)
|
||||
@@ -244,6 +245,9 @@ sequenceDiagram
|
||||
和 TestClient 因而共享同一 fail-fast 语义。
|
||||
- **引擎预热 fail-fast**:同步/异步数据库引擎在单线程期完成首次创建,
|
||||
避免调度器放出大量线程后再创建引擎导致连接锁竞争。
|
||||
- **类型化请求装配**:`startup/context.py` 的 frozen slots `HostRuntime` 是 lifespan 内唯一宿主
|
||||
上下文,`api/context.py` 从 `app.state` 收窄到具体领域能力。Agent 会话已迁移,不再通过
|
||||
字符串仓储键定位;`ApiDataPorts` 暂作未迁移领域的同实例兼容 Facade。
|
||||
- **安全模式**:`MOVIEPILOT_SAFE_MODE` 会跳过插件、定时器、监控器、命令与工作流,用于故障自救。
|
||||
- **进程拓扑**:全功能 V3 强制 `API_WORKERS=1`,避免每个 worker 重复启动插件和后台控制面;安全模式可临时使用多 worker 诊断,但不是正式扩容方案。
|
||||
- **健康语义**:`/health/live` 只确认进程和事件循环可响应;`/health/ready` 仅在数据库
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
> 审计范围:宿主后端;排除 `app/plugins/**` 运行时插件副本
|
||||
> 规范优先级:`AGENTS.md` 与 `docs/rules/` 高于本文
|
||||
> 相关文档:`docs/architecture-overview.md`、`docs/refactor/backend-architecture-governance.md`、`docs/refactor/backend-module-refactor-compatibility.md`
|
||||
> 实施进度:阶段 0(ARCH-201~203)、阶段 1(ARCH-210~212)与阶段 2(ARCH-220~222)已完成,后续任务按 ID 独立提交和回滚
|
||||
> 实施进度:阶段 0(ARCH-201~203)、阶段 1(ARCH-210~212)、阶段 2(ARCH-220~222)与 ARCH-230 已完成,后续任务按 ID 独立提交和回滚
|
||||
|
||||
## 1. 结论先行
|
||||
|
||||
@@ -448,6 +448,17 @@ app/api/dependencies/ # 按领域拆分依赖工厂
|
||||
- 不创建一个更大的全局 `services: dict[str, Any]`;
|
||||
- 不把完整 HostRuntime 传入 Domain 或每个小函数。
|
||||
|
||||
**实施记录(2026-08-21)**:
|
||||
|
||||
- `app/startup/context.py` 定义 frozen slots `HostRuntime` 与首个窄能力
|
||||
`AgentChatRuntime`,仓储、Session、UoW 字段均为具体 Protocol 工厂,不是字符串字典。
|
||||
- `init_modules()` 保留零参数兼容签名并返回本次 lifespan 唯一 Runtime;生命周期组件把结果挂到
|
||||
`app.state.host_runtime`。`app/api/context.py` 只向 Depends 暴露 Agent chat 的最小能力。
|
||||
- `get_agent_chat_service` 不再读取全局 `_ports` 或 `"agent_chat"` key;该 key 已从宿主和测试
|
||||
`ApiDataPorts.repositories` 删除。未迁移领域仍通过 `compatibility_api_data` 使用同一个实例。
|
||||
- fake Runtime 请求测试证明仓储与 UoW 共享同一请求会话,且无需加载真实 DB engine、
|
||||
PluginManager 或其他运行时服务;旧 `configure_api_data_ports()` 调用形态继续可用。
|
||||
|
||||
#### ARCH-231:按领域拆分 API dependency 与 presentation
|
||||
|
||||
**目标**:`app/api/deps.py` 从 512 行集中装配点变成兼容聚合入口,端点只负责 HTTP 解析、鉴权依赖和结果映射。
|
||||
|
||||
@@ -94,6 +94,11 @@ create additional top-level directory categories.
|
||||
`app/startup/` remains the established composition root and is not nested under
|
||||
runtime. It injects providers and callbacks, orders initialization/shutdown and
|
||||
decides restart policy. Lower-level runtime modules must not import startup.
|
||||
Startup publishes its frozen, slotted `HostRuntime` through FastAPI `app.state`.
|
||||
API dependencies must narrow that object to a domain runtime (for example,
|
||||
`AgentChatRuntime`) instead of adding a string key to a global service map.
|
||||
Legacy registries may delegate the same object while domains migrate, but they
|
||||
must not construct a second set of service instances.
|
||||
|
||||
`app.schemas` and `app.db` are compatibility facades, not implementation
|
||||
dependency hubs. Host code imports concrete schema submodules; the schema root
|
||||
|
||||
Reference in New Issue
Block a user