mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-11-02 21:34:32 +08:00
refactor(runtime): govern dependency module naming
This commit is contained in:
@@ -70,7 +70,7 @@ MoviePilot V3 已经形成较清晰的模块化单体:`foundation`、`domain`
|
||||
|
||||
| 指标 | 当前值 | 解释 |
|
||||
|---|---:|---|
|
||||
| 宿主 Python 模块 / 内部依赖边 | 932 / 7,886 | `dependency-baseline.json` 当前快照 |
|
||||
| 宿主 Python 模块 / 内部依赖边 | 933 / 7,890 | `dependency-baseline.json` 当前快照 |
|
||||
| 非平凡 SCC | 1 | 仅保留精确 containment 的 29 模块 TMDB 移植包环 |
|
||||
| 跨层 DB 边界债务 | 0 | Application、Chain、API、Agent、Runtime、Workflow 到 DB 的受控债务均为零 |
|
||||
| Model/Oper 事务债务 | 0 | 自建 Session、自动事务装饰器、直接 commit/rollback 等基线均为零 |
|
||||
@@ -79,7 +79,7 @@ MoviePilot V3 已经形成较清晰的模块化单体:`foundation`、`domain`
|
||||
| Python 源码量 | 约 271,400 行 | 60 个文件超过 1,000 行,14 个超过 2,000 行 |
|
||||
| 长方法 | 281 个超过 80 行 | 67 个超过 150 行,23 个超过 250 行;大量是私有方法 |
|
||||
| 全量 mypy 历史债务 | 10,982 / 599 文件 | strict frontier 当前覆盖 41 个文件,本批迁移路径的类型债务已清零 |
|
||||
| Ruff 历史诊断 | 671 | 低水位门禁通过,但规则集只覆盖 `E4/E7/E9/F/I` |
|
||||
| Ruff 历史诊断 | 667 | 低水位门禁通过,但规则集只覆盖 `E4/E7/E9/F/I` |
|
||||
| 覆盖率低水位 | Application 80.75%,Domain 79.32% | Chain、Runtime、Agent、Adapter、Startup 未进入包级覆盖率门禁 |
|
||||
|
||||
### 3.3 热点文件
|
||||
|
||||
@@ -192,7 +192,7 @@ SDK/Compat。领域查询与写入继续使用 Application 所属的冻结 DTO/P
|
||||
|---|---|---|
|
||||
| `app/foundation/` | 无状态、无配置、无 I/O 的底层原语:反射/动态导入、加密、DOM、单例、文本、URL、版本比较 | `reflection.py`、`crypto.py`、`singleton.py` |
|
||||
| `app/domain/` | 纯 MoviePilot 业务语义:媒体上下文、识别解析、站点状态解释、磁力语义、NFO 刮削 | `context.py`、`metainfo.py`、`meta/`、`scraper.py` |
|
||||
| `app/runtime/` | 进程级运行机制:配置、进程拓扑、事件、完整日志、缓存契约与内存后端、任务所有权、执行/关联上下文、并发、调度、限流、本地化、GC、重启状态 | `config.py`、`events.py`、`event/`、`tasks.py`、`execution.py`、`correlation.py`、`log.py`、`cache.py` |
|
||||
| `app/runtime/` | 进程级运行机制:配置、进程拓扑、事件、完整日志、缓存契约与内存后端、运行依赖 profile 与原生载荷激活检测、任务所有权、执行/关联上下文、并发、调度、限流、本地化、GC、重启状态 | `config.py`、`events.py`、`event/`、`dependencies/`、`tasks.py`、`execution.py`、`correlation.py`、`log.py`、`cache.py` |
|
||||
| `app/runtime/extensions/` | 模块 / 插件 / 配置化服务 / 托管资源的发现、注册与生命周期适配;旧管理器文件保留稳定 ABI 门面,具体实现拆在主题子包 | `module_manager.py`、`plugin_manager.py`、`plugin/` |
|
||||
| `app/runtime/compat/` | 仅标准库的精确旧模块、包与符号导入路由;不是业务实现,也不是通用 re-export 层 | `manifest.py`、`imports.py` |
|
||||
| `app/adapters/network/` | 通用 HTTP、浏览器、DNS、Cloudflare、IP 传输机制 | `http.py`、`browser.py` |
|
||||
@@ -220,6 +220,8 @@ SDK/Compat。领域查询与写入继续使用 Application 所属的冻结 DTO/P
|
||||
| `app/workflow/` | 工作流引擎 | — |
|
||||
| `app/plugins/` | 插件运行时副本/覆盖目录,由插件管理器加载;不是官方插件源码或宿主架构实现,架构审计以插件仓库与宿主边界为准 | — |
|
||||
|
||||
`app/runtime/dependencies/` 是一个同名能力包:`profile.py` 只负责解释器 ABI 对应的依赖组,`native.py` 只负责已加载原生发行包的快照与变更检测。包根不重复导出实现,宿主直接导入职责子模块;旧的平级 `dependencies.py` 与 `native_dependencies.py` 已退出规范实现。
|
||||
|
||||
---
|
||||
|
||||
## 四、启动与生命周期
|
||||
@@ -726,8 +728,8 @@ flowchart LR
|
||||
|
||||
| 指标 | 当前值 |
|
||||
|---|---:|
|
||||
| Python 模块 | 932 |
|
||||
| 内部导入边 | 7,886 |
|
||||
| Python 模块 | 933 |
|
||||
| 内部导入边 | 7,890 |
|
||||
| 非平凡 SCC | 1(精确 containment 的 TMDB 移植包环) |
|
||||
| Application / Chain 具体 Adapter 直连 | 0 / 0 |
|
||||
| Direct egress | 55(债务已清零,55 条精确 containment) |
|
||||
|
||||
@@ -139,7 +139,7 @@ canonical 主程序;兼容只经统一 Compat/SDK 门面提供。
|
||||
| S3-L3 Scheduler | `VERIFIED` | S2-L3 | 旧 `app/scheduler.py` 已退役并迁入 `app.scheduler` 同名包;catalog、execution/bridge/progress、`ExecutionRegistry`、reconciler、lifecycle 与 maintenance 已分离,业务 callable 由 startup 经 `SchedulerServices` 注入,包内无参 Chain 构造清零;功能/生命周期 215 项、架构/兼容/文档 189 项通过,官方插件基线语义未变化 |
|
||||
| S3-L4 DownloadChain | `DELIVERED` | S1-L6 | `7941fd921`:旧单体退役;selection、submission、batch、history、post-processing 等职责进入同名包单一 owner,提交后动作遵守新完成语义;锁定全量 `7162 passed, 9 skipped`,远端 `0/0` |
|
||||
| S3-L5 SearchChain | `DELIVERED` | S2-L7 | `1c145d716`:旧单体退役并由同名职责包承接;稳定 ABI、官方插件兼容、类型/复杂度门禁和锁定全量 `7222 passed, 9 skipped` 通过;远端 `0/0` |
|
||||
| S3-L5.1 Runtime dependencies 命名治理 | `ACTIVE` | S3-L5 | `dependencies.py` 与 `native_dependencies.py` 退役为 `runtime/dependencies/` 同名包;单词子模块、无包根重复导出,并把规则写入 `docs/rules/07-naming-conventions.md` 及机器门禁 |
|
||||
| S3-L5.1 Runtime dependencies 命名治理 | `VERIFIED` | S3-L5 | `dependencies.py` 与 `native_dependencies.py` 退役为 `runtime/dependencies/` 同名包;单词子模块、无包根重复导出,并把规则写入 `docs/rules/07-naming-conventions.md` 及机器门禁 |
|
||||
| S3-L6 MediaChain | `PLANNED` | S2-L2 | recognition、source projection、music alignment、cache 分离,兼容仅经统一层 |
|
||||
| S3-L7 Agent/System/Plugin API | `PLANNED` | S2,S1-L6 | WebAgent SSE/file/audio、nettest/log/update/market 用例进入 Application,endpoint 只做传输适配 |
|
||||
|
||||
@@ -176,7 +176,7 @@ canonical 主程序;兼容只经统一 Compat/SDK 门面提供。
|
||||
|
||||
### S3-L5.1 Runtime dependencies 命名治理
|
||||
|
||||
**Status:** `ACTIVE`
|
||||
**Status:** `VERIFIED`
|
||||
|
||||
**Outcome**
|
||||
|
||||
@@ -199,6 +199,14 @@ canonical 主程序;兼容只经统一 Compat/SDK 门面提供。
|
||||
- 运行依赖分组、插件原生依赖激活、插件安装/包管理专项及架构/质量门禁全部通过。
|
||||
- 提交推送后确认远端 SHA、祖先关系和 ahead/behind `0/0`。
|
||||
|
||||
**Evidence(2026-08-29)**
|
||||
|
||||
- 平铺实现已删除,`app/runtime/dependencies/` 仅有 `__init__.py`、`profile.py`、`native.py`;包根只有包说明,宿主导入全部直达职责子模块。
|
||||
- Docker 更新边界同时覆盖新包载荷与旧版本 `dependencies.py` 快照回滚,未把旧实现恢复到主程序。
|
||||
- 官方插件仓最新远端 `aa40b961a2093474a77edd9eed88844ff07425ac` 对旧路径及全部公开符号零命中,因此未新增无消费者的 SDK/Compat 债务。
|
||||
- 运行依赖、原生激活、插件安装/包管理及架构专项 `406 passed`;最终架构/CI/Docker 门禁 `182 passed`。
|
||||
- 锁定全量 `7224 passed, 9 skipped`;Pylint `10.00/10` 且重复率 `0.000%`;mypy、Ruff(历史诊断降至 `667`)、复杂度和依赖基线门禁全部通过。
|
||||
|
||||
### S3-L5 SearchChain
|
||||
|
||||
**Status:** `DELIVERED`
|
||||
|
||||
@@ -100,6 +100,7 @@ directory categories.
|
||||
| `app/runtime/execution.py` | Shared sync/async execution and cross-thread submission boundary with correlation propagation |
|
||||
| `app/runtime/correlation.py` | Request/cross-thread correlation context and safe propagation into logs and child work |
|
||||
| `app/runtime/state.py` | Process restart and update state |
|
||||
| `app/runtime/dependencies/` | Runtime dependency profile selection in `profile.py` and loaded native payload activation detection in `native.py`; the package root contains no implementation or host re-exports |
|
||||
| `app/runtime/extensions/` | Module, plugin, configured-service and managed-resource discovery/registration/lifecycle adapters |
|
||||
| `app/runtime/compat/` | Standard-library-only exact legacy import routing, resource preflight scanning and DEBUG diagnostics |
|
||||
|
||||
@@ -114,6 +115,12 @@ 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.
|
||||
The retired flat `app/runtime/dependencies.py` and
|
||||
`app/runtime/native_dependencies.py` modules must not return. Canonical host
|
||||
callers import `app.runtime.dependencies.profile` or
|
||||
`app.runtime.dependencies.native` directly; the package root is not an export
|
||||
facade, and plugin compatibility is added only through an exact SDK/Compat route
|
||||
when a verified plugin contract requires it.
|
||||
Canonical host consumers of the process-wide module, plugin, scheduler and
|
||||
system-configuration runtimes must call `get_module_manager()`,
|
||||
`get_plugin_manager()`, `get_scheduler()` and `get_configured_system_config()`
|
||||
@@ -883,4 +890,4 @@ imports, entrypoint (`api`/`agent`/`monitor`/`workflow`/`doctor`) imports of
|
||||
modules only through `run_module` dispatch), and downloader SDK
|
||||
(`qbittorrentapi`, `transmission_rpc`) imports inside `app/chain`.
|
||||
|
||||
*Last Updated: 2026-08-28*
|
||||
*Last Updated: 2026-08-29*
|
||||
|
||||
@@ -16,6 +16,17 @@ All new code must follow these conventions. Consistent naming is how the codebas
|
||||
| Alembic migrations | Auto-generated by Alembic; do not rename | `20240101_add_column.py` |
|
||||
| Skill directories | `<kebab-case>/` | `transfer-failed-retry/`, `moviepilot-cli/` |
|
||||
|
||||
### Production Module Creation Gate
|
||||
|
||||
新增或拆分生产模块时必须按以下顺序决策,代码评审与架构测试以此为准:
|
||||
|
||||
1. 优先扩展当前职责 owner;只因文件变长或需要一个私有辅助类,不得新建平级模块。
|
||||
2. 一个能力需要第二个生产文件时,必须在同一次变更中改为同名目录包,禁止继续增加 `<capability>_<role>.py` 平级文件。
|
||||
3. 包内子文件使用准确、可独立说明职责的单个小写名词,如 `dependencies/profile.py` 与 `dependencies/native.py`;不得使用 `native_dependencies.py`、`transfer_execution.py` 这类重复能力名。
|
||||
4. 包根 `__init__.py` 只允许包说明和确有外部契约证据的公开门面,不得复制实现,也不得为宿主代码重复导出子模块符号;宿主必须直接导入 owner 子模块。
|
||||
5. 旧路径兼容只能在确认真实插件消费者后,通过 `app/sdk/` 或 `app/runtime/compat/` 做精确映射;不得为假设消费者保留旧源码、通配映射或双份导出。
|
||||
6. 新增文件前必须同步更新本规则对应的机器门禁;若现有门禁不能表达该命名约束,应在同一变更中补充 `tests/test_architecture_dependencies.py`。
|
||||
|
||||
---
|
||||
|
||||
## Classes
|
||||
@@ -120,8 +131,9 @@ All new code must follow these conventions. Consistent naming is how the codebas
|
||||
| `configuration.get("RssUrls")` | `configuration.get(SystemConfigKey.RssUrls)` |
|
||||
| `class subscribe_oper:` | `class SubscribeOper:` |
|
||||
| `transfer.py` + `transfer_execution.py` | `transfer/workflow.py` + `transfer/execution.py` |
|
||||
| `dependencies.py` + `native_dependencies.py` | `dependencies/profile.py` + `dependencies/native.py` |
|
||||
| Package-root host re-exports for an old path | Exact SDK/Compat mapping; host code imports the owning child module |
|
||||
| `MessageChannel.Telegram`(新代码) | `NotificationChannel.Telegram` |
|
||||
| `Notification(title=...)`(新代码) | `Message(title=...)` |
|
||||
|
||||
*Last Updated: 2026-08-27*
|
||||
*Last Updated: 2026-08-29*
|
||||
|
||||
@@ -28,7 +28,7 @@ V3t 的目标不是让所有请求都更快。它主要改善可并行的 Python
|
||||
- `runtime-free-threaded`
|
||||
|
||||
`tool.uv.conflicts` 保证两个组不能同时解析。Docker 的两个构建 stage 分别固定选择对应组;源码升级、
|
||||
启动恢复和插件安装后的宿主恢复由 `app.runtime.dependencies.runtime_dependency_group()` 根据当前
|
||||
启动恢复和插件安装后的宿主恢复由 `app.runtime.dependencies.profile.runtime_dependency_group()` 根据当前
|
||||
解释器的 `Py_GIL_DISABLED` 构建标志选择 profile。
|
||||
|
||||
依赖选择不得改为镜像标签判断,也不得在业务模块中按包名散落 V3/V3t 分支。Dockerfile 只选择运行
|
||||
|
||||
Reference in New Issue
Block a user