Files
Unlucky-Launcher/crates/core/src/download/blocking.rs
T
AskaEth bc41dfcf7d
CI / fmt (rustfmt --check) (push) Canceled after 0s
CI / clippy (ubuntu-latest) (push) Canceled after 0s
CI / clippy (windows-latest) (push) Canceled after 0s
CI / test (ubuntu-latest) (push) Canceled after 0s
CI / test (windows-latest) (push) Canceled after 0s
CI / build release (ubuntu-latest) (push) Canceled after 0s
CI / build release (windows-latest) (push) Canceled after 0s
Guards / core 零 UI 守门 (push) Canceled after 0s
Guards / 文件行数 ≤400 守门 (push) Canceled after 0s
Guards / 依赖许可与来源(cargo-deny) (push) Canceled after 0s
Unlucky Launcher v0.0.1-alpha
Rust 原生单文件 Minecraft 启动器:CLI 完整可用(install/launch/accounts/java/diagnose/agent),
MCP server 接入外部 Agent 工具,GUI 开发中。
2026-10-31 21:54:10 +08:00

56 lines
2.1 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! 同步桥:让**非 async 宿主**驱动异步下载引擎。
//!
//! `core::download` 的引擎是异步的(tokio + reqwest),GUI 侧自带运行时;
//! 但 headless 消费者(`crates/cli` 的 `ull`)不依赖 tokio,也不该为一次安装
//! 把整个异步运行时依赖树拉进 CLI 的 manifest(D18:CLI 依赖树保持干净)。
//!
//! 因此把「建一个短命运行时 + 跑完整段 future」这两件事收在 core 里:
//!
//! ```ignore
//! let outcome = unlucky_core::download::blocking::block_on(async { /* 规划 + 下载 */ });
//! ```
//!
//! 约定:**整段**安装流程包在一次 `block_on` 里(同一个运行时),不要每次下载都建一个——
//! reqwest 的连接池绑定在创建它的运行时上,跨运行时会退化甚至报「dispatch task is gone」。
//!
//! 这是给「单线程 CLI」用的逃生口,不是通用设施:app 层请直接用原生异步。
use std::future::Future;
/// 在一个临时 tokio 多线程运行时上跑完 `future`。
///
/// 运行时随调用结束销毁,因此适合「一条命令一次阻塞」的 CLI 生命周期。
///
/// # Panics
///
/// 运行时建不起来(系统资源耗尽)时 panic:此时进程已无法继续,早点暴露比静默降级好。
/// 在已有 tokio 运行时上下文里调用同样会 panic(tokio 不允许嵌套 `block_on`)。
pub fn block_on<F: Future>(future: F) -> F::Output {
let runtime = tokio::runtime::Builder::new_multi_thread()
.worker_threads(2)
.thread_name("ull-blocking")
.enable_all()
.build()
.expect("创建 tokio 运行时失败(内存/线程资源不足)");
runtime.block_on(future)
}
#[cfg(test)]
mod tests {
use super::block_on;
#[test]
fn drives_a_plain_future_to_completion() {
assert_eq!(block_on(async { 1 + 1 }), 2);
}
#[test]
fn drives_tokio_timers() {
let start = std::time::Instant::now();
block_on(async {
tokio::time::sleep(std::time::Duration::from_millis(5)).await;
});
assert!(start.elapsed() >= std::time::Duration::from_millis(5));
}
}