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.
This commit is contained in:
pj committed 2026-06-22 12:01:25 -04:00
1 parent 3177b2f1eb
commit 39609fbd09
1 file changed
+27 -23
+27 -23
View File
@@ -176,36 +176,40 @@ fn collect_grammar(harper: &mut Harper, text: &str, chars: &[char], issues: &mut
#[tauri::command] #[tauri::command]
pub async fn proof_text( pub async fn proof_text(
app: tauri::AppHandle, app: tauri::AppHandle,
state: tauri::State<'_, ProofState>,
text: String, text: String,
spelling: bool, spelling: bool,
grammar: bool, grammar: bool,
) -> Result<Vec<Issue>, String> { ) -> Result<Vec<Issue>, String> {
let mut guard = state.inner().lock().map_err(|e| e.to_string())?; tauri::async_runtime::spawn_blocking(move || -> Result<Vec<Issue>, String> {
if guard.is_none() { let state = app.state::<ProofState>();
*guard = Some(Engine { let mut guard = state.lock().map_err(|e| e.to_string())?;
speller: None, if guard.is_none() {
harper: None, *guard = Some(Engine {
custom: load_custom(&app), speller: None,
}); harper: None,
} custom: load_custom(&app),
let engine = guard.as_mut().unwrap(); });
}
let engine = guard.as_mut().unwrap();
let chars: Vec<char> = text.chars().collect(); let chars: Vec<char> = text.chars().collect();
let mut issues = Vec::new(); let mut issues = Vec::new();
if spelling { if spelling {
if engine.speller.is_none() { if engine.speller.is_none() {
engine.speller = Some(build_speller(&app)?); 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() {
if grammar { engine.harper = Some(build_harper());
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] #[tauri::command]