Open jacobbuck72 opened 1 month ago
I think it is a race condition and I've made a work-around...
I’ve narrowed it down to the fact that in app.restart() it is triggering the RunEvent::ExitRequested and right after it is calling process::restart(). And at least on my MacBook M2 Pro the process:restart() method starts loading the Info.plist but before this I/O is done the RunEvent:Exit is already dispatched ad the process killed before process:restarts() manages to fully spawn the new process. So it seems like a race condition between two threads trying to exit the process.
I’ve resolved this by calling app.exit(RESTART_EXIT_CODE) in stead and then on RunEvent::Exit I trigger process:update() (which will call exit(0) when done but first doing app.cleanup_before_exit() before calling process::update() since eventloop is stopped here.
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
let app = Builder::default()
.plugin(tauri_plugin_single_instance::init(|app, args, _cwd| {
log::warn!("Single instance version {}", app.package_info().version.to_string());
}))
.plugin(tauri_plugin_updater::Builder::new().build())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_process::init())
...
let is_restart_requested = Arc::new(AtomicBool::new(false));
let is_restart_requested_clone = is_restart_requested.clone();
// Attempt to better handle removal of system tray on Windows
app.run(move |app_handle, event| match event {
tauri::RunEvent::ExitRequested { code, ..} => {
if code.unwrap() == RESTART_EXIT_CODE {
// RunEvent does not hold the exit code so we store it separately
is_restart_requested.store(true, Ordering::SeqCst);
}
}
tauri::RunEvent::Exit => {
if is_restart_requested_clone.load(Ordering::SeqCst) {
app_handle.cleanup_before_exit();
let env = _app_handle.env();
tauri::process::restart(&env); // this will call exit(0) so we'll not return to the event loop
}
},
_ => {}
});
Perhaps it would be a good idea if the runtime would handle this restart in the RunEvent::Exit handling (after callback) and with the RunEvent::Exit passing both "api" and "code" with the option to call api.prevent_restart() - or api.prevent_exit() should cancel both exit and restart in the RunEvent::Exit step. Then app.restart() would just need to trigger RunEvent::ExitRequested(RESTART_EXIT_CODE).
Hi, I just came to leave a +1 - I'm new to Tauri and I suspect I'm seeing the same issue happening.
+1
Describe the bug
When a new version on macOS has been downloaded and installed the app closes down but does not start again.
It is a desktop app for macOS and Windows. It has a main window that the user can close/hide while the icon tray remains. So on WindowEvent::CloseRequested we prevent closing the app. Could this cause the issue?
We just migrated to Tauri 2 so had to provide our own dialog (see updater.rs below) and doing version check and triggering download, install and restart (which fails on macOS).
The app is built with our self hosted GitLab CI/CD pipeline producing a static updater.json uploaded to S3 together with the artefacts:
Important part of my main.rs:
I have created updater.rs:
capabilities/main.json
Important parts of tauri.config.json:
zx
Reproduction
I have not tried building a simple app since this would require a full CI pipeline and new S3 bucket to test. But it's the same every time I do this:
Expected behavior
After installing the update the app should start again.
Full
tauri info
outputStack trace
Additional context
No response