feat(m165): 下载引擎按数据根跨请求复用(运行时常驻 + 构造次数守卫)
宿主侧以前每次请求都现建一个 DownloadEngine:连接池、信号量限流、 健康度记忆、内容寻址缓存索引全部清零。现在改成按数据根共享一个实例。 - core: 新增 download::shared(进程级登记处,键 = 缓存根)—— engine_for / forget / constructions;region/health/cache/mirrors 的装配 收在这一个 build() 里(持锁构造只做本地 I/O,不联网) - core: download::blocking 改成进程内唯一常驻运行时。reqwest 的连接池绑在 驱动连接的运行时上,引擎复用必须配运行时常驻,否则复用的是个装满死连接的池 - presenter: host::engine::engine 返回 Arc<DownloadEngine>(共享实例), addon/update/versions/java/authlib 等全部调用点随之改;新增 forget 供 「重新检测地区」失效(否则进程级引擎下那句话不成立) - presenter: addon 详情页把「项目 + 版本列表」两次 block_on 收成一次 失败分类 / 镜像回退 / Retry-After 语义未改动(error.rs、http.rs、engine.rs 的 候选循环一字未动)。 守卫(都带变异实证): - shared::tests::one_engine_per_cache_root + host::engine::tests:: host_requests_share_one_engine:断言 constructions(root) == 1(不是只看结果) - shared::tests::pooled_connection_survives_across_block_on_calls:127.0.0.1 回环服务统计 accept 次数,两次 block_on 必须只拨号一次 验证:cargo test -p unlucky-core --lib(608 过)、5 个 download 集成 target(42 过)、 cargo test -p unlucky-presenter --lib(267 过)、cargo clippy --all-targets、 cargo fmt --check 全绿。真站点(Modrinth/CurseForge/BMCLAPI)未打,见报告。
This commit is contained in:
1 parent
b4e6fbf8c1
commit
46389d61fd
11 files changed
+486
-48
No files matched your search
@@ -21,7 +21,8 @@
|
||||
//! `Cargo.lock` 里已有的 `reqwest` 0.12 + `tokio` + `serde_json` 就是全部。生产实现
|
||||
//! [`EngineTransport`] 走 `DownloadEngine::download_bytes`,于是**信号量限流、源健康度、
|
||||
//! 指数退避、错误分类**全由 `core::download` 提供,本模块不写第二个重试循环,也不持有第二个
|
||||
//! `reqwest::Client`(与 `addon::import::fetch` 同一条纪律)。
|
||||
//! `reqwest::Client`(与 `addon::import::fetch` 同一条纪律)。那个引擎是宿主侧的进程级共享实例
|
||||
//! (M165:`download::shared::engine_for`),所以元数据请求与文件下载共用同一条连接池与限流。
|
||||
//!
|
||||
//! 没有 POST:Modrinth 的批量接口(`POST /v2/version_files`)需要 POST 请求体,而引擎的
|
||||
//! `DownloadRequest` 没有请求体字段。补全路径因此按**单摘要 GET** 逐条查(循环在
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
//! (与 `addon::import::fetch` 的纪律同源)。镜像策略同理:`mirrors.json` 里没有
|
||||
//! `api.modrinth.com` 的前缀规则 ⇒ 元数据请求永远是直连,只有真正的文件下载才会被镜像
|
||||
//! 规则命中(国内 gh-proxy 那条也只看 GitHub host)。
|
||||
//!
|
||||
//! 引擎本身由宿主提供**且是进程级共享的**(M165:`download::shared::engine_for`,一个数据根
|
||||
//! 一个):`EngineTransport` 只借一个 `&DownloadEngine`,不负责建也不负责销毁。于是
|
||||
//! 「检索 → 详情 → 装文件」这一串请求复用同一条连接池、同一个限流闸门、同一份镜像健康度——
|
||||
//! 这正是本模块当初拒绝自己造 client 的同一个理由,只是从「模块内不重复造」扩到了「跨请求不重复造」。
|
||||
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
||||
Reference in new issue
Block a user