fix(local-asr): 用 tauri::async_runtime 取代 tokio::spawn — 修点击下载即崩

崩溃栈:local_asr_download_model → DownloadManager::start → tokio::spawn
→ panic("there is no reactor running")。

根因:Tauri 同步 command 在 main thread 上下文跑,没进 tokio runtime;
tokio::spawn 直接 panic。换 tauri::async_runtime::spawn —— 它走 Tauri
持有的 runtime handle,不依赖调用方上下文。

同步把 local_provider.rs 的 spawn_blocking 也换成 tauri::async_runtime
版本(虽然现在在 async 路径上调没事,保持一致防回归)。

附带把 qwen_ffi.rs 的 `unsafe extern "C"` block 改回经典 extern block,
匹配 CLAUDE.md 声明的 rust-version = "1.77"(前者要 1.82+)。
This commit is contained in:
baiqing committed 2026-05-05 09:49:33 +08:00
1 parent dd43a7801d
commit 839ad76c5b
3 files changed
+12 -3

No files matched your search

@@ -201,7 +201,11 @@ impl DownloadManager {
};
let manager = Arc::clone(self);
tokio::spawn(async move {
// 用 tauri::async_runtime::spawn 而不是 tokio::spawn ——
// Tauri 同步 command 不在 tokio runtime 上下文里,调 tokio::spawn 会立刻
// panic("there is no reactor running, must be called from the context of a Tokio 1.x runtime")。
// tauri::async_runtime 走 Tauri 持有的 runtime handle,不依赖调用方上下文。
tauri::async_runtime::spawn(async move {
let result = run_download(&app, model_id, mirror, &flag).await;
manager.cancel_flags.lock().remove(&key);
match result {
@@ -65,8 +65,11 @@ impl LocalQwenAsr {
}));
// qwen_transcribe_stream 是阻塞调用;用 spawn_blocking 防止占住 tokio runtime。
// 用 tauri::async_runtime::spawn_blocking 而非 tokio 的 —— 同 download.rs 注释,
// 走 Tauri 持有的 runtime handle,不依赖调用方上下文(虽然这里目前都在 async 路径上调,
// 但保持一致更稳)。
let engine = Arc::clone(&self.engine);
let text = tokio::task::spawn_blocking(move || engine.transcribe_stream(&samples_f32))
let text = tauri::async_runtime::spawn_blocking(move || engine.transcribe_stream(&samples_f32))
.await
.context("transcribe spawn_blocking join 失败")?
.context("qwen_transcribe_stream 失败")?;
@@ -14,7 +14,9 @@ pub struct QwenCtx {
/// `typedef void (*qwen_token_cb)(const char *piece, void *userdata);`
pub type QwenTokenCb = unsafe extern "C" fn(piece: *const c_char, userdata: *mut c_void);
unsafe extern "C" {
// 用经典 `extern "C"` block 而非 `unsafe extern "C"` block — 后者需 Rust
// 1.82+;CLAUDE.md 声明 rust-version = "1.77",避免给二次贡献者制造毛刺。
extern "C" {
pub fn qwen_load(model_dir: *const c_char) -> *mut QwenCtx;
pub fn qwen_free(ctx: *mut QwenCtx);