tenseleyflow/hyprkvm / d3af6ee

Browse files

fix: improve daemon restart with setsid and socket verification

- Use setsid --fork to properly daemonize spawned process
- Verify daemon started by checking socket availability
- Increase wait times for more reliable restart
- Add logging for exe path during restart
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
d3af6ee8488aeb4811c4b4db8ff8374c8c9c143d
Parents
31f17c5
Tree
e51777a

1 changed file

StatusFile+-
M hyprkvm-daemon/src/gui/app.rs 45 8
hyprkvm-daemon/src/gui/app.rsmodified
@@ -253,12 +253,19 @@ impl HyprKvmGui {
253253
                 let _ = reader.read_line(&mut response);
254254
             }
255255
             // Give daemon time to shutdown
256
-            std::thread::sleep(std::time::Duration::from_millis(500));
256
+            std::thread::sleep(std::time::Duration::from_millis(1000));
257257
         }
258258
 
259259
         // Now spawn a new daemon process
260
+        // Try current_exe first, fall back to PATH lookup
260261
         let exe = std::env::current_exe().unwrap_or_else(|_| "hyprkvm".into());
261
-        match Command::new(&exe)
262
+        tracing::info!("Restarting daemon with exe: {:?}", exe);
263
+
264
+        // Use setsid to create a new session so daemon survives GUI exit
265
+        // This is the Unix way to properly daemonize
266
+        match Command::new("setsid")
267
+            .arg("--fork")
268
+            .arg(&exe)
262269
             .arg("daemon")
263270
             .stdin(std::process::Stdio::null())
264271
             .stdout(std::process::Stdio::null())
@@ -267,14 +274,44 @@ impl HyprKvmGui {
267274
         {
268275
             Ok(_) => {
269276
                 // Wait a moment for daemon to start
270
-                std::thread::sleep(std::time::Duration::from_millis(500));
271
-                self.state.error = None;
272
-                self.state.needs_restart = false;
273
-                self.state.success = Some("Daemon restarted".to_string());
277
+                std::thread::sleep(std::time::Duration::from_millis(1000));
278
+
279
+                // Verify daemon actually started by checking socket
280
+                if UnixStream::connect(&socket_path).is_ok() {
281
+                    self.state.error = None;
282
+                    self.state.needs_restart = false;
283
+                    self.state.success = Some("Daemon restarted".to_string());
284
+                } else {
285
+                    self.state.error = Some("Daemon spawn succeeded but socket not available".to_string());
286
+                    self.state.needs_restart = true;
287
+                }
274288
             }
275289
             Err(e) => {
276
-                self.state.error = Some(format!("Failed to start daemon: {}", e));
277
-                self.state.needs_restart = false;
290
+                // setsid not available, try direct spawn
291
+                tracing::warn!("setsid failed: {}, trying direct spawn", e);
292
+                match Command::new(&exe)
293
+                    .arg("daemon")
294
+                    .stdin(std::process::Stdio::null())
295
+                    .stdout(std::process::Stdio::null())
296
+                    .stderr(std::process::Stdio::null())
297
+                    .spawn()
298
+                {
299
+                    Ok(_) => {
300
+                        std::thread::sleep(std::time::Duration::from_millis(1000));
301
+                        if UnixStream::connect(&socket_path).is_ok() {
302
+                            self.state.error = None;
303
+                            self.state.needs_restart = false;
304
+                            self.state.success = Some("Daemon restarted".to_string());
305
+                        } else {
306
+                            self.state.error = Some("Daemon spawn succeeded but socket not available".to_string());
307
+                            self.state.needs_restart = true;
308
+                        }
309
+                    }
310
+                    Err(e2) => {
311
+                        self.state.error = Some(format!("Failed to start daemon: {}", e2));
312
+                        self.state.needs_restart = false;
313
+                    }
314
+                }
278315
             }
279316
         }
280317
     }