From fd93334a21907f959018e1b1f5df747a98d186c8 Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 4 Nov 2026 01:11:50 +0100 Subject: processes: add timeouts and keep decoding off the runtime --- src/commands/math.rs | 19 ++++++++++++++----- src/commands/qr.rs | 12 ++++++++---- src/commands/utilities.rs | 15 +++++++++++---- 3 files changed, 33 insertions(+), 13 deletions(-) (limited to 'src/commands') diff --git a/src/commands/math.rs b/src/commands/math.rs index 43a7de8..25ddaab 100644 --- a/src/commands/math.rs +++ b/src/commands/math.rs @@ -57,11 +57,20 @@ pub async fn math( return Ok(()); } - let output = tokio::process::Command::new("qalc") - .arg(&equation) - .output() - .await - .map_err(|e| Error::Custom(lang::fmt_math_qalc_err(&e)))?; + let output = match tokio::time::timeout( + std::time::Duration::from_secs(5), + tokio::process::Command::new("qalc") + .arg(&equation) + .output(), + ) + .await + { + Ok(result) => result.map_err(|e| Error::Custom(lang::fmt_math_qalc_err(&e)))?, + Err(_) => { + ctx.say(lang::L_MATH_NO_RESULT).await?; + return Ok(()); + } + }; let result = String::from_utf8_lossy(&output.stdout).trim().to_string(); if result.is_empty() { diff --git a/src/commands/qr.rs b/src/commands/qr.rs index 26232ee..c0b8af0 100644 --- a/src/commands/qr.rs +++ b/src/commands/qr.rs @@ -61,10 +61,14 @@ pub async fn dekodowanie( .await? .bytes() .await?; - let img = image::load_from_memory(&img_data)?; - let gray = img.to_luma8(); - - let decoded = decode_qr_simple(&gray); + // Decoding is CPU-heavy: keep it off the async runtime. + let img_data = img_data.to_vec(); + let decoded = tokio::task::spawn_blocking(move || { + let img = image::load_from_memory(&img_data).ok()?; + let gray = img.to_luma8(); + decode_qr_simple(&gray) + }) + .await?; match decoded { Some(text) => { ctx.say(lang::fmt_qr_decoded(&text)).await?; diff --git a/src/commands/utilities.rs b/src/commands/utilities.rs index bf93491..c26fd0e 100644 --- a/src/commands/utilities.rs +++ b/src/commands/utilities.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use poise::serenity_prelude as serenity; use tracing::warn; @@ -524,10 +526,15 @@ async fn run_download( } cmd.arg("--").arg(sanitize_yt_url(url)); - let output = cmd - .output() - .await - .map_err(|e| Error::Custom(lang::fmt_ytdlp_err(&e)))?; + let output = match tokio::time::timeout(Duration::from_secs(600), cmd.output()).await { + Ok(result) => result.map_err(|e| Error::Custom(lang::fmt_ytdlp_err(&e)))?, + Err(_) => { + let _ = tokio::fs::remove_dir_all(&dl_dir).await; + ctx.say(lang::fmt_download_failed("download timed out after 10 minutes")) + .await?; + return Ok(()); + } + }; if !output.status.success() { let stderr = String::from_utf8_lossy(&output.stderr); // Keep the full yt-dlp trace in the logs; the user only sees the -- cgit v1.2.3