Skip to content

Commit 787104e

Browse files
committed
fix: properly manage gptme-server lifecycle and fix dev mode CORS
- Add proper cleanup of gptme-server process when Tauri app exits - Use different CORS origins for dev (http://localhost:5701) vs production (tauri://localhost) - Store server process reference in app state for termination on window close - Fix server not quitting when app quits in both dev and release modes
1 parent 20c7eb3 commit 787104e

File tree

1 file changed

+43
-5
lines changed

1 file changed

+43
-5
lines changed

src-tauri/src/lib.rs

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
use std::sync::{Arc, Mutex};
2+
use tauri::Manager;
13
use tauri_plugin_log::{Target, TargetKind};
2-
use tauri_plugin_shell::ShellExt;
4+
use tauri_plugin_shell::{process::CommandChild, ShellExt};
35

46
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
57
#[tauri::command]
@@ -29,13 +31,26 @@ pub fn run() {
2931

3032
let app_handle = app.handle().clone();
3133

34+
// Store child process reference for cleanup
35+
let child_process: Arc<Mutex<Option<CommandChild>>> = Arc::new(Mutex::new(None));
36+
let child_for_cleanup = child_process.clone();
37+
3238
// Spawn gptme-server with output capture
3339
tauri::async_runtime::spawn(async move {
40+
// Determine CORS origin based on build mode
41+
let cors_origin = if cfg!(debug_assertions) {
42+
"http://localhost:5701" // Dev mode
43+
} else {
44+
"tauri://localhost" // Production mode
45+
};
46+
47+
log::info!("Starting gptme-server with CORS origin: {}", cors_origin);
48+
3449
let sidecar_command = app_handle
3550
.shell()
3651
.sidecar("gptme-server")
3752
.unwrap()
38-
.args(["--cors-origin", "tauri://localhost"]);
53+
.args(["--cors-origin", cors_origin]);
3954

4055
match sidecar_command.spawn() {
4156
Ok((mut rx, child)) => {
@@ -44,6 +59,11 @@ pub fn run() {
4459
child.pid()
4560
);
4661

62+
// Store child process reference
63+
if let Ok(mut child_ref) = child_process.lock() {
64+
*child_ref = Some(child);
65+
}
66+
4767
// Handle server output
4868
tauri::async_runtime::spawn(async move {
4969
while let Some(event) = rx.recv().await {
@@ -80,18 +100,36 @@ pub fn run() {
80100
}
81101
}
82102
});
83-
84-
// The child process termination is handled through the event stream above
85-
// No need to explicitly wait here since CommandEvent::Terminated will fire
86103
}
87104
Err(e) => {
88105
log::error!("Failed to start gptme-server: {}", e);
89106
}
90107
}
91108
});
92109

110+
// Store child process reference in app state for cleanup
111+
app.manage(child_for_cleanup);
112+
93113
Ok(())
94114
})
115+
.on_window_event(|window, event| {
116+
// Handle window close event to cleanup server
117+
if let tauri::WindowEvent::CloseRequested { .. } = event {
118+
log::info!("Window close requested, cleaning up gptme-server...");
119+
120+
{
121+
let child_ref = window.state::<Arc<Mutex<Option<CommandChild>>>>().clone();
122+
if let Ok(mut child) = child_ref.lock() {
123+
if let Some(process) = child.take() {
124+
match process.kill() {
125+
Ok(_) => log::info!("gptme-server process terminated successfully"),
126+
Err(e) => log::error!("Failed to terminate gptme-server: {}", e),
127+
}
128+
}
129+
};
130+
}
131+
}
132+
})
95133
.run(tauri::generate_context!())
96134
.expect("error while running tauri application");
97135
}

0 commit comments

Comments
 (0)