mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
fix(desktop): preserve relaunch through mesh shutdown (#1966)
Signed-off-by: Wes <wesbillman@users.noreply.github.com> Co-authored-by: Pinky <44b8e82baa6e0e254e0208d68f335c283c94e7b78dd1fa10d5a49d3f13dd0435@sprout-oss.stage.blox.sqprod.co>
This commit is contained in:
Generated
+1
@@ -1010,6 +1010,7 @@ dependencies = [
|
||||
"notify-rust",
|
||||
"objc2-app-kit",
|
||||
"opus",
|
||||
"plist",
|
||||
"png 0.18.1",
|
||||
"regex",
|
||||
"reqwest 0.13.4",
|
||||
|
||||
@@ -47,6 +47,7 @@ keyring = { version = "3.6.3", default-features = false, features = ["apple-nati
|
||||
security-framework = { version = "3.7.0", features = ["OSX_10_15"] }
|
||||
window-vibrancy = "0.6"
|
||||
user-idle = { version = "0.6", default-features = false }
|
||||
plist = "1"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
windows-sys = { version = "0.61", features = ["Win32_Security", "Win32_Storage_FileSystem", "Win32_System_JobObjects", "Win32_System_Registry", "Win32_System_Threading", "Win32_Foundation"] }
|
||||
|
||||
@@ -51,10 +51,8 @@ use huddle::{
|
||||
};
|
||||
use managed_agents::{backfill_persona_snapshots, ensure_nest, try_regenerate_nest};
|
||||
#[cfg(all(feature = "mesh-llm", target_os = "macos"))]
|
||||
use shutdown::hard_exit_after_mesh_shutdown;
|
||||
use shutdown::shutdown_managed_agents;
|
||||
#[cfg(feature = "mesh-llm")]
|
||||
use shutdown::shutdown_mesh_runtime;
|
||||
use shutdown::{hard_exit_after_mesh_shutdown, relaunch_after_mesh_shutdown};
|
||||
use shutdown::{is_restart_request, shut_down_app};
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
@@ -967,19 +965,20 @@ pub fn run() {
|
||||
shutdown::install_signal_handler(app.handle().clone(), Arc::clone(&shutdown_done));
|
||||
|
||||
let run_shutdown_done = Arc::clone(&shutdown_done);
|
||||
let restart_requested = Arc::new(AtomicBool::new(false));
|
||||
app.run(move |app_handle, event| match event {
|
||||
RunEvent::ExitRequested { .. } | RunEvent::Exit => {
|
||||
app_handle
|
||||
.state::<AppState>()
|
||||
.shutdown_started
|
||||
.store(true, Ordering::SeqCst);
|
||||
if !run_shutdown_done.swap(true, Ordering::SeqCst) {
|
||||
prevent_sleep::release(&app_handle.state::<AppState>().prevent_sleep);
|
||||
if let Err(error) = shutdown_managed_agents(app_handle) {
|
||||
eprintln!("buzz-desktop: failed to stop managed agents: {error}");
|
||||
}
|
||||
#[cfg(feature = "mesh-llm")]
|
||||
shutdown_mesh_runtime(app_handle);
|
||||
RunEvent::ExitRequested { code, .. } => {
|
||||
if is_restart_request(code) {
|
||||
restart_requested.store(true, Ordering::SeqCst);
|
||||
}
|
||||
shut_down_app(app_handle, &run_shutdown_done);
|
||||
}
|
||||
RunEvent::Exit => {
|
||||
shut_down_app(app_handle, &run_shutdown_done);
|
||||
|
||||
#[cfg(all(feature = "mesh-llm", target_os = "macos"))]
|
||||
if restart_requested.load(Ordering::SeqCst) {
|
||||
relaunch_after_mesh_shutdown(app_handle);
|
||||
}
|
||||
|
||||
// AppKit terminates through libc exit(), which runs C++ static
|
||||
|
||||
@@ -5,7 +5,27 @@ use crate::managed_agents::{
|
||||
self, kill_stale_tracked_processes, load_managed_agents, save_managed_agents,
|
||||
sync_managed_agent_processes, BackendKind, ManagedAgentProcess,
|
||||
};
|
||||
use crate::util;
|
||||
use crate::{prevent_sleep, util};
|
||||
|
||||
pub(crate) fn is_restart_request(code: Option<i32>) -> bool {
|
||||
code == Some(tauri::RESTART_EXIT_CODE)
|
||||
}
|
||||
|
||||
pub(crate) fn shut_down_app(app: &tauri::AppHandle, shutdown_done: &std::sync::atomic::AtomicBool) {
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
app.state::<AppState>()
|
||||
.shutdown_started
|
||||
.store(true, Ordering::SeqCst);
|
||||
if !shutdown_done.swap(true, Ordering::SeqCst) {
|
||||
prevent_sleep::release(&app.state::<AppState>().prevent_sleep);
|
||||
if let Err(error) = shutdown_managed_agents(app) {
|
||||
eprintln!("buzz-desktop: failed to stop managed agents: {error}");
|
||||
}
|
||||
#[cfg(feature = "mesh-llm")]
|
||||
shutdown_mesh_runtime(app);
|
||||
}
|
||||
}
|
||||
|
||||
/// Install SIGINT/SIGTERM/SIGHUP cleanup on ctrlc's dedicated handler thread.
|
||||
#[cfg(unix)]
|
||||
@@ -33,6 +53,43 @@ pub(crate) fn install_signal_handler(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "mesh-llm", target_os = "macos"))]
|
||||
fn updated_macos_binary(current_binary: &std::path::Path) -> Option<std::path::PathBuf> {
|
||||
let macos_directory = current_binary.parent()?;
|
||||
if macos_directory.file_name()? != "MacOS" {
|
||||
return None;
|
||||
}
|
||||
let contents_directory = macos_directory.parent()?;
|
||||
if contents_directory.file_name()? != "Contents" {
|
||||
return None;
|
||||
}
|
||||
let info_plist =
|
||||
plist::from_file::<_, plist::Dictionary>(contents_directory.join("Info.plist")).ok()?;
|
||||
let binary_name = info_plist.get("CFBundleExecutable")?.as_string()?;
|
||||
Some(macos_directory.join(binary_name))
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "mesh-llm", target_os = "macos"))]
|
||||
pub(crate) fn relaunch_after_mesh_shutdown(app: &tauri::AppHandle) -> ! {
|
||||
use std::process::Command;
|
||||
|
||||
tauri_plugin_single_instance::destroy(app);
|
||||
let env = app.env();
|
||||
match tauri::process::current_binary(&env) {
|
||||
Ok(current_binary) => {
|
||||
let binary = updated_macos_binary(¤t_binary).unwrap_or(current_binary);
|
||||
if let Err(error) = Command::new(binary)
|
||||
.args(env.args_os.iter().skip(1))
|
||||
.spawn()
|
||||
{
|
||||
eprintln!("buzz-desktop: failed to relaunch app: {error}");
|
||||
}
|
||||
}
|
||||
Err(error) => eprintln!("buzz-desktop: failed to locate app for relaunch: {error}"),
|
||||
}
|
||||
hard_exit_after_mesh_shutdown();
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "mesh-llm", target_os = "macos"))]
|
||||
pub(crate) fn hard_exit_after_mesh_shutdown() -> ! {
|
||||
// SAFETY: all Buzz-managed subprocesses and the embedded Mesh runtime have
|
||||
@@ -201,3 +258,15 @@ pub(crate) fn shutdown_managed_agents(app: &tauri::AppHandle) -> Result<(), Stri
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::is_restart_request;
|
||||
|
||||
#[test]
|
||||
fn only_tauri_restart_exit_code_requests_a_relaunch() {
|
||||
assert!(is_restart_request(Some(tauri::RESTART_EXIT_CODE)));
|
||||
assert!(!is_restart_request(None));
|
||||
assert!(!is_restart_request(Some(0)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user