The sidecar process was orphaned when the Tauri app closed, leaving ports 8080/8081 in use. On next launch the new sidecar couldn't bind those ports and failed to start. Added RunEvent::Exit handler that stops the sidecar before the app process terminates. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
88 lines
3.0 KiB
Rust
88 lines
3.0 KiB
Rust
mod sidecar;
|
|
|
|
use std::sync::Mutex;
|
|
use tauri::Manager;
|
|
|
|
/// App log directory, set during setup.
|
|
static LOG_DIR: std::sync::OnceLock<std::path::PathBuf> = std::sync::OnceLock::new();
|
|
|
|
/// Write a log message to the app's log file (for debugging).
|
|
#[tauri::command]
|
|
fn write_log(message: String) {
|
|
if let Some(log_dir) = LOG_DIR.get() {
|
|
let log_path = log_dir.join("frontend.log");
|
|
use std::io::Write;
|
|
if let Ok(mut f) = std::fs::OpenOptions::new()
|
|
.create(true)
|
|
.append(true)
|
|
.open(&log_path)
|
|
{
|
|
let _ = writeln!(f, "[{}] {}", chrono::Local::now().format("%H:%M:%S%.3f"), message);
|
|
}
|
|
}
|
|
eprintln!("[frontend] {}", message);
|
|
}
|
|
|
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
pub fn run() {
|
|
tauri::Builder::default()
|
|
.plugin(tauri_plugin_shell::init())
|
|
.plugin(tauri_plugin_dialog::init())
|
|
.plugin(tauri_plugin_process::init())
|
|
.manage(sidecar::ManagedSidecar(std::sync::Arc::new(Mutex::new(
|
|
sidecar::SidecarManager::new(),
|
|
))))
|
|
.setup(|app| {
|
|
let resource_dir = app
|
|
.path()
|
|
.resource_dir()
|
|
.expect("failed to resolve resource dir");
|
|
let data_dir = app
|
|
.path()
|
|
.app_data_dir()
|
|
.expect("failed to resolve app data dir");
|
|
|
|
std::fs::create_dir_all(&data_dir).expect("failed to create app data dir");
|
|
|
|
// Set up logging
|
|
LOG_DIR.set(data_dir.clone()).ok();
|
|
let log_path = data_dir.join("app.log");
|
|
if let Ok(mut f) = std::fs::OpenOptions::new()
|
|
.create(true)
|
|
.append(true)
|
|
.open(&log_path)
|
|
{
|
|
use std::io::Write;
|
|
let _ = writeln!(f, "\n=== App started at {} ===", chrono::Local::now());
|
|
let _ = writeln!(f, "Resource dir: {}", resource_dir.display());
|
|
let _ = writeln!(f, "Data dir: {}", data_dir.display());
|
|
}
|
|
|
|
sidecar::init_dirs(resource_dir, data_dir);
|
|
Ok(())
|
|
})
|
|
.invoke_handler(tauri::generate_handler![
|
|
sidecar::check_sidecar,
|
|
sidecar::download_sidecar,
|
|
sidecar::check_sidecar_update,
|
|
sidecar::get_sidecar_port,
|
|
sidecar::start_sidecar,
|
|
sidecar::stop_sidecar,
|
|
sidecar::reset_sidecar,
|
|
write_log,
|
|
])
|
|
.build(tauri::generate_context!())
|
|
.expect("error while building tauri application")
|
|
.run(|app, event| {
|
|
if let tauri::RunEvent::Exit = event {
|
|
// Stop the sidecar when the app exits
|
|
if let Some(state) = app.try_state::<sidecar::ManagedSidecar>() {
|
|
if let Ok(mut mgr) = state.0.lock() {
|
|
eprintln!("[app] Stopping sidecar on exit...");
|
|
mgr.stop();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|