From 39609fbd091723276588a157c301e0ac9c6cb3a2 Mon Sep 17 00:00:00 2001 From: PJ Date: Mon, 22 Jun 2026 12:01:25 -0400 Subject: [PATCH] perf(proofing): run proof_text on a blocking thread proof_text loaded the dictionary and ran spell/grammar checks synchronously inside an async command, blocking an async-runtime worker and holding the engine mutex for the whole call. Move the work to spawn_blocking so IPC stays responsive under load. --- src-tauri/src/proofing.rs | 50 +++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/src-tauri/src/proofing.rs b/src-tauri/src/proofing.rs index 9a8cace..a1f0aea 100644 --- a/src-tauri/src/proofing.rs +++ b/src-tauri/src/proofing.rs @@ -176,36 +176,40 @@ fn collect_grammar(harper: &mut Harper, text: &str, chars: &[char], issues: &mut #[tauri::command] pub async fn proof_text( app: tauri::AppHandle, - state: tauri::State<'_, ProofState>, text: String, spelling: bool, grammar: bool, ) -> Result, String> { - let mut guard = state.inner().lock().map_err(|e| e.to_string())?; - if guard.is_none() { - *guard = Some(Engine { - speller: None, - harper: None, - custom: load_custom(&app), - }); - } - let engine = guard.as_mut().unwrap(); + tauri::async_runtime::spawn_blocking(move || -> Result, String> { + let state = app.state::(); + let mut guard = state.lock().map_err(|e| e.to_string())?; + if guard.is_none() { + *guard = Some(Engine { + speller: None, + harper: None, + custom: load_custom(&app), + }); + } + let engine = guard.as_mut().unwrap(); - let chars: Vec = text.chars().collect(); - let mut issues = Vec::new(); - if spelling { - if engine.speller.is_none() { - engine.speller = Some(build_speller(&app)?); + let chars: Vec = text.chars().collect(); + let mut issues = Vec::new(); + if spelling { + if engine.speller.is_none() { + engine.speller = Some(build_speller(&app)?); + } + collect_spelling(engine.speller.as_ref().unwrap(), &engine.custom, &chars, &mut issues); } - collect_spelling(engine.speller.as_ref().unwrap(), &engine.custom, &chars, &mut issues); - } - if grammar { - if engine.harper.is_none() { - engine.harper = Some(build_harper()); + if grammar { + if engine.harper.is_none() { + engine.harper = Some(build_harper()); + } + collect_grammar(engine.harper.as_mut().unwrap(), &text, &chars, &mut issues); } - collect_grammar(engine.harper.as_mut().unwrap(), &text, &chars, &mut issues); - } - Ok(issues) + Ok(issues) + }) + .await + .map_err(|e| e.to_string())? } #[tauri::command]