mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-11-04 06:15:14 +08:00
refactor(startup): centralize runtime composition
This commit is contained in:
@@ -62,7 +62,7 @@ MoviePilot V3 已经形成较清晰的模块化单体:`foundation`、`domain`
|
||||
| `chain` | 多入口复用的用例编排与 Module 动态分发已稳定,包根 SCC 已清零 | God object、私有长方法、无参构造和资源物化过重 |
|
||||
| `db/oper` | Model/Oper 已不自建 Session、不自行提交 | 无 Session Facade 仍被宿主组合根注入,业务操作可能拆成多个事务 |
|
||||
| `db/adapters` | 已有显式 Session/UoW 的参考切片 | Port 返回类型不够稳定;Outbox 的 stage 与自提交 dispatcher store 混在一个类型 |
|
||||
| `startup` | 已是 HostRuntime 和生命周期组合根;Chain 兼容上下文由 `composition/chain.py` 独立装配 | `initializers/modules.py` 仍有其他领域高扇出和具体对象目录装配 |
|
||||
| `startup` | `composition/runtime.py` 已成为 HostRuntime、领域 Runtime 与旧 ApiData 投影唯一 owner;Chain/Agent 复用同一 RuntimeDependencies | `initializers/modules.py` 仍保留启动顺序与跨领域发布调用,高扇出需由生命周期验收继续约束 |
|
||||
| API/Command/Scheduler | 多数入口已转向 Chain/Application;Scheduler 单体已拆为同名职责包并由 startup 注入业务 callable | Agent/System/Plugin 等入口仍承担较多业务与 I/O 编排 |
|
||||
| `sdk`/`compat` | 精确映射、稳定插件 ABI 和宿主 canonical 路径已落地 | SDK 仍暴露部分可变全局对象/具体 Manager,只能渐进收窄,不能直接删除 |
|
||||
|
||||
@@ -70,7 +70,7 @@ MoviePilot V3 已经形成较清晰的模块化单体:`foundation`、`domain`
|
||||
|
||||
| 指标 | 当前值 | 解释 |
|
||||
|---|---:|---|
|
||||
| 宿主 Python 模块 / 内部依赖边 | 971 / 8,306 | `dependency-baseline.json` 当前快照 |
|
||||
| 宿主 Python 模块 / 内部依赖边 | 972 / 8,301 | `dependency-baseline.json` 当前快照 |
|
||||
| 非平凡 SCC | 1 | 仅保留精确 containment 的 29 模块 TMDB 移植包环 |
|
||||
| 跨层 DB 边界债务 | 0 | Application、Chain、API、Agent、Runtime、Workflow 到 DB 的受控债务均为零 |
|
||||
| Model/Oper 事务债务 | 0 | 自建 Session、自动事务装饰器、直接 commit/rollback 等基线均为零 |
|
||||
@@ -78,8 +78,8 @@ MoviePilot V3 已经形成较清晰的模块化单体:`foundation`、`domain`
|
||||
| Event Contract | 53 | 均已有 payload model,但当前全部是 diagnostic enforcement |
|
||||
| Python 源码量 | 约 298,700 行 | 60 个文件超过 1,000 行,10 个超过 2,000 行 |
|
||||
| 长方法 | 299 个超过 80 行 | 70 个超过 150 行,23 个超过 250 行;大量是私有方法 |
|
||||
| 全量 mypy 历史债务 | 10,335 / 593 文件 | 新 Chain composition owner 零类型债,`modules.py` 低水位下降 1;strict frontier 当前覆盖 41 个文件 |
|
||||
| Ruff 历史诊断 | 648 | 低水位门禁通过,但规则集只覆盖 `E4/E7/E9/F/I` |
|
||||
| 全量 mypy 历史债务 | 10,320 / 592 文件 | Runtime 唯一组合 owner 零新增类型债,`modules.py` 低水位下降 4;strict frontier 当前覆盖 41 个文件 |
|
||||
| Ruff 历史诊断 | 644 | 低水位门禁通过,但规则集只覆盖 `E4/E7/E9/F/I` |
|
||||
| 覆盖率低水位 | Application 81.00%,Domain 80.67% | Chain、Runtime、Agent、Adapter、Startup 未进入包级覆盖率门禁 |
|
||||
|
||||
### 3.3 热点文件
|
||||
@@ -675,8 +675,9 @@ Pylint 10/10、Ruff、mypy/复杂度 ratchet、宿主与最新官方插件基线
|
||||
- [x] L4.2 已将 network、security、agent、server、outbox 与 Chain 装配迁入单词型
|
||||
`startup/composition/*` owner;Agent composition 在 Worker 启动后读取容量并共享同一数据和任务对象,
|
||||
Chain 通过 provider 保持插件无参构造兼容,旧 Transfer command 只在真实调用时延迟导入。
|
||||
- [ ] 继续将 HostRuntime 剩余构造移到 `startup/composition/runtime.py`,最终让 initializer
|
||||
只负责顺序、注册和是否重启的决策。
|
||||
- [x] L4.3 已将 HostRuntime、命名领域 Runtime 和旧 `ApiDataPorts` 投影统一移到单词型
|
||||
`startup/composition/runtime.py`;`RuntimeDependencies` 由 Agent、Chain、HostRuntime 复用,
|
||||
`HostRuntime.tasks` 显式绑定 lifecycle 的 TaskRegistry,Chain 不再二次构造 transfer execution。
|
||||
- [ ] 保留生命周期 manifest 和顺序快照;高扇出在组合根是允许的,但业务实现不能继续沉积其中。
|
||||
|
||||
### ARCH-204 收敛 sync/async 重复与测试存量
|
||||
|
||||
@@ -284,13 +284,18 @@ sequenceDiagram
|
||||
从 `HostRuntime.configuration` 获取 frozen 配置快照。系统设置管理 API 通过
|
||||
`HostRuntime.settings` 的窄服务读写可变部署设置,业务域不接触 Settings 实例;生产与测试组合根统一
|
||||
复用 `startup/composition/configuration.py` 的映射、快照加载与发布。`startup/composition/database.py`
|
||||
持有数据库 worker、兼容事务 runner、查询/插件持久化和旧 `ApiDataPorts` 的具体装配;initializer
|
||||
只保留顺序调用。`startup/composition/chain.py` 集中构造无参 Chain 兼容上下文及其持久化、事件、
|
||||
持有数据库 worker、兼容事务 runner、查询与插件持久化;`startup/composition/runtime.py` 是
|
||||
`HostRuntime`、全部命名领域 Runtime 和旧 `ApiDataPorts` 投影的唯一构造/发布 owner。它先构造
|
||||
一份 frozen `RuntimeDependencies`,Agent、Chain 与 HostRuntime 复用同一仓储、transfer execution
|
||||
ledger 和消息对象,导入阶段不启动数据库 worker 或消息队列;initializer 只保留顺序调用。
|
||||
`startup/composition/chain.py` 集中构造无参 Chain 兼容上下文及其持久化、事件、
|
||||
Outbox、消息和模块分发依赖,并延迟绑定旧 Transfer command 与壁纸 Chain,避免组合根导入环。
|
||||
`startup/composition/security.py` 统一装配认证、用户查询、PassKey 与 Web 访问
|
||||
provider,并将同一 `AuthenticationRuntime` 交给 HostRuntime;`startup/composition/network.py` 统一
|
||||
装配网络应用端口;`startup/composition/agent.py` 构造并发布唯一的 Agent 数据、会话和自主任务对象,
|
||||
`HostRuntime`、工具管理器与 Scheduler 复用同一对象身份。`ApiDataPorts` 仅保留旧导入 ABI,
|
||||
provider,并把持久化工厂交给 runtime owner 投影为 `AuthenticationRuntime`;
|
||||
`startup/composition/network.py` 统一装配网络应用端口;`startup/composition/agent.py` 构造并发布
|
||||
唯一的 Agent 数据、会话持久化和自主任务对象,由 runtime owner 投影 `AgentChatRuntime`,
|
||||
`HostRuntime`、工具管理器与 Scheduler 复用同一对象身份。`ApiDataPorts` 严格从同一 HostRuntime
|
||||
字段投影,仅保留旧导入 ABI,
|
||||
不参与正式请求链路。
|
||||
- **安全模式**:`MOVIEPILOT_SAFE_MODE` 会跳过插件、定时器、监控器、命令与工作流,用于故障自救。
|
||||
- **Scheduler 同名职责包**:旧 `app/scheduler.py` 单体已退役;`catalog.py` 负责作业目录和计划投影,
|
||||
@@ -749,8 +754,8 @@ flowchart LR
|
||||
|
||||
| 指标 | 当前值 |
|
||||
|---|---:|
|
||||
| Python 模块 | 971 |
|
||||
| 内部导入边 | 8,306 |
|
||||
| Python 模块 | 972 |
|
||||
| 内部导入边 | 8,301 |
|
||||
| 非平凡 SCC | 1(精确 containment 的 TMDB 移植包环) |
|
||||
| Application / Chain 具体 Adapter 直连 | 0 / 0 |
|
||||
| Direct egress | 53(债务已清零,53 条精确 containment) |
|
||||
|
||||
@@ -139,15 +139,22 @@ not startup. Lower-level runtime modules must not import startup.
|
||||
`startup/composition/configuration.py` owns configuration snapshot loading, typed
|
||||
runtime/settings construction and publication. `startup/composition/database.py`
|
||||
owns the process database worker, compatibility transaction runner, query services,
|
||||
plugin persistence and legacy API data-port wiring. Initializers call these owners in
|
||||
plugin persistence and workflow query wiring. Initializers call these owners in
|
||||
startup order and must not recreate their concrete construction.
|
||||
`startup/composition/runtime.py` is the sole constructor of `HostRuntime`, its named
|
||||
domain Runtime projections and the legacy `ApiDataPorts` projection. It first creates
|
||||
one frozen `RuntimeDependencies` aggregate; Agent, Chain and HostRuntime must reuse the
|
||||
same repositories, transfer-execution ledger and message owners rather than constructing
|
||||
parallel instances. Importing this owner remains cold: concrete DB adapters are resolved
|
||||
only when composition functions run, and FastAPI `app.state` publication remains owned by
|
||||
the lifecycle layer.
|
||||
`startup/composition/chain.py` owns the no-argument Chain compatibility context,
|
||||
typed persistence/dispatch object graph, lazy legacy Transfer command binding and
|
||||
wallpaper-provider publication. `initializers/modules.py` only passes the already
|
||||
constructed repositories in startup order and must not recreate those dependencies.
|
||||
wallpaper-provider publication. `initializers/modules.py` passes the already constructed
|
||||
`RuntimeDependencies` in startup order and must not recreate those dependencies.
|
||||
`startup/composition/security.py` owns authentication, user lookup, PassKey and Web
|
||||
access provider assembly; `initializers/modules.py` only invokes that owner and places
|
||||
its returned `AuthenticationRuntime` into the host runtime.
|
||||
access provider assembly; it returns the persistence factories needed by the runtime
|
||||
owner, which alone constructs `AuthenticationRuntime`.
|
||||
`startup/composition/network.py` owns concrete network-test, image, internal-address
|
||||
and message-ingress Adapter wiring
|
||||
while retaining lazy RuntimeSettings reads. Initializers call these owners in
|
||||
@@ -160,8 +167,9 @@ startup order and must not recreate its concrete construction.
|
||||
construction and registration, including lazy local-data readers and external
|
||||
transport callbacks; `initializers/modules.py` retains only its startup-order call
|
||||
and the later explicit network warmup. Database runtime
|
||||
`startup/composition/agent.py` owns the single `AgentDataContext`, `AgentChatRuntime`,
|
||||
chat persistence and autonomous-task repository/execution service set. It may accept
|
||||
`startup/composition/agent.py` owns the single `AgentDataContext`, chat persistence and
|
||||
autonomous-task repository/execution service set. The runtime owner projects those same
|
||||
objects into `AgentChatRuntime`. Agent composition may accept
|
||||
the Agent initializer's data-context registrar as a callback, but must not import
|
||||
`startup.initializers`; tool-manager, scheduler and Agent activation order remains in
|
||||
the initializer. Database runtime ownership rejects overlapping lifespans; after a
|
||||
|
||||
Reference in New Issue
Block a user