diff --git a/.vscode/settings.json b/.vscode/settings.json index 12ae327..53f4e09 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -81,6 +81,7 @@ "letterboxing", "libatk", "libayatana", + "libc", "libcairo", "libgdk", "libglib", @@ -128,6 +129,7 @@ "plasmohq", "platformdirs", "prefs", + "PRIO", "propertylist", "psutil", "pycache", @@ -147,6 +149,7 @@ "screeninfo", "selectables", "serde", + "setpriority", "SETTINGCHANGE", "setuptools", "shadcn", diff --git a/src-tauri/src/bin/proxy_server.rs b/src-tauri/src/bin/proxy_server.rs index 6b5eb65..af853aa 100644 --- a/src-tauri/src/bin/proxy_server.rs +++ b/src-tauri/src/bin/proxy_server.rs @@ -6,6 +6,55 @@ use donutbrowser_lib::proxy_server::run_proxy_server; use donutbrowser_lib::proxy_storage::get_proxy_config; use std::process; +fn set_high_priority() { + #[cfg(unix)] + { + unsafe { + // Set high priority (negative nice value = higher priority) + // -10 is a reasonably high priority without being too aggressive + // This may fail without elevated privileges, which is fine + let result = libc::setpriority(libc::PRIO_PROCESS, 0, -10); + if result == 0 { + log::info!("Set process priority to -10 (high priority)"); + } else { + // Try a less aggressive priority if -10 fails + let result = libc::setpriority(libc::PRIO_PROCESS, 0, -5); + if result == 0 { + log::info!("Set process priority to -5 (above normal)"); + } + } + } + } + + #[cfg(target_os = "linux")] + { + // Lower OOM score so this process is less likely to be killed under memory pressure + // Valid range is -1000 to 1000, lower = less likely to be killed + // -500 is a reasonable value that makes us less likely to be killed + if let Err(e) = std::fs::write("/proc/self/oom_score_adj", "-500") { + log::debug!("Could not set OOM score adjustment: {}", e); + } else { + log::info!("Set OOM score adjustment to -500"); + } + } + + #[cfg(windows)] + { + use windows::Win32::System::Threading::{ + GetCurrentProcess, SetPriorityClass, ABOVE_NORMAL_PRIORITY_CLASS, + }; + + unsafe { + let process = GetCurrentProcess(); + if SetPriorityClass(process, ABOVE_NORMAL_PRIORITY_CLASS).is_ok() { + log::info!("Set process priority to ABOVE_NORMAL_PRIORITY_CLASS"); + } else { + log::debug!("Could not set process priority class"); + } + } + } +} + fn build_proxy_url( proxy_type: &str, host: &str, @@ -230,6 +279,9 @@ async fn main() { .expect("action is required"); if action == "start" { + // Set high priority so this process is killed last under resource pressure + set_high_priority(); + log::error!("Proxy worker starting, looking for config id: {}", id); log::error!("Process PID: {}", std::process::id()); diff --git a/src-tauri/src/proxy_runner.rs b/src-tauri/src/proxy_runner.rs index bfea908..253822e 100644 --- a/src-tauri/src/proxy_runner.rs +++ b/src-tauri/src/proxy_runner.rs @@ -79,6 +79,13 @@ pub async fn start_proxy_process_with_profile( cmd.pre_exec(|| { // Create a new process group so the process survives parent exit libc::setsid(); + + // Set high priority so the proxy is killed last under resource pressure + // Negative nice value = higher priority. Try -10, fall back to -5 if it fails. + if libc::setpriority(libc::PRIO_PROCESS, 0, -10) != 0 { + let _ = libc::setpriority(libc::PRIO_PROCESS, 0, -5); + } + Ok(()) }); } @@ -106,6 +113,10 @@ pub async fn start_proxy_process_with_profile( { use std::os::windows::process::CommandExt; use std::process::Command as StdCommand; + use windows::Win32::Foundation::CloseHandle; + use windows::Win32::System::Threading::{ + OpenProcess, SetPriorityClass, ABOVE_NORMAL_PRIORITY_CLASS, PROCESS_SET_INFORMATION, + }; let mut cmd = StdCommand::new(&exe); cmd.arg("proxy-worker"); @@ -124,6 +135,14 @@ pub async fn start_proxy_process_with_profile( let child = cmd.spawn()?; let pid = child.id(); + // Set high priority so the proxy is killed last under resource pressure + unsafe { + if let Ok(handle) = OpenProcess(PROCESS_SET_INFORMATION, false, pid) { + let _ = SetPriorityClass(handle, ABOVE_NORMAL_PRIORITY_CLASS); + let _ = CloseHandle(handle); + } + } + // Store PID { let mut processes = PROXY_PROCESSES.lock().unwrap();