mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 00:35:38 +08:00
fix: restart app failed (#4974)
* fix: failed to restart app * chore: cleanup * chore: cargo fmt * chore: use AsyncHandler * chore: clippy * chore: update
This commit is contained in:
@@ -3,7 +3,7 @@ use crate::{
|
|||||||
core::{CoreManager, handle, tray},
|
core::{CoreManager, handle, tray},
|
||||||
logging_error,
|
logging_error,
|
||||||
process::AsyncHandler,
|
process::AsyncHandler,
|
||||||
utils::{logging::Type, resolve},
|
utils::{self, logging::Type, resolve},
|
||||||
};
|
};
|
||||||
use serde_yaml_ng::{Mapping, Value};
|
use serde_yaml_ng::{Mapping, Value};
|
||||||
|
|
||||||
@@ -23,6 +23,7 @@ pub async fn restart_clash_core() {
|
|||||||
|
|
||||||
/// Restart the application
|
/// Restart the application
|
||||||
pub async fn restart_app() {
|
pub async fn restart_app() {
|
||||||
|
utils::server::shutdown_embedded_server();
|
||||||
if let Err(err) = resolve::resolve_reset_async().await {
|
if let Err(err) = resolve::resolve_reset_async().await {
|
||||||
handle::Handle::notice_message(
|
handle::Handle::notice_message(
|
||||||
"restart_app::error",
|
"restart_app::error",
|
||||||
@@ -34,45 +35,6 @@ pub async fn restart_app() {
|
|||||||
|
|
||||||
let app_handle = handle::Handle::app_handle();
|
let app_handle = handle::Handle::app_handle();
|
||||||
app_handle.restart();
|
app_handle.restart();
|
||||||
// TODO: PR Ref: https://github.com/clash-verge-rev/clash-verge-rev/pull/4960
|
|
||||||
// handle::Handle::notice_message("restart_app::info", "Restarting application...");
|
|
||||||
|
|
||||||
// // Use the manual restart method consistently to ensure reliability across platforms
|
|
||||||
// // This addresses the issue where app_handle.restart() doesn't work properly on Windows
|
|
||||||
// let current_exe = match env::current_exe() {
|
|
||||||
// Ok(path) => path,
|
|
||||||
// Err(_) => {
|
|
||||||
// // If we can't get the current executable path, try to use the fallback method
|
|
||||||
// if let Some(app_handle) = handle::Handle::global().app_handle() {
|
|
||||||
// app_handle.restart();
|
|
||||||
// }
|
|
||||||
// exit(1); // If we reach here, either app_handle was None or restart() failed to restart
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// let mut cmd = Command::new(current_exe);
|
|
||||||
// cmd.args(env::args().skip(1));
|
|
||||||
|
|
||||||
// match cmd.spawn() {
|
|
||||||
// Ok(child) => {
|
|
||||||
// log::info!(target: "app", "New application instance started with PID: {}", child.id());
|
|
||||||
// // Successfully started new process, now exit current process
|
|
||||||
// if let Some(app_handle) = handle::Handle::global().app_handle() {
|
|
||||||
// app_handle.exit(0);
|
|
||||||
// } else {
|
|
||||||
// exit(0);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Err(e) => {
|
|
||||||
// log::error!(target: "app", "Failed to start new application instance: {}", e);
|
|
||||||
// // If manual spawn fails, try the original restart method as a last resort
|
|
||||||
// if let Some(app_handle) = handle::Handle::global().app_handle() {
|
|
||||||
// app_handle.restart();
|
|
||||||
// } else {
|
|
||||||
// exit(1);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_change_clash_mode() {
|
fn after_change_clash_mode() {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::utils;
|
||||||
use crate::utils::window_manager::WindowManager;
|
use crate::utils::window_manager::WindowManager;
|
||||||
use crate::{
|
use crate::{
|
||||||
config::Config,
|
config::Config,
|
||||||
@@ -21,6 +22,7 @@ async fn open_or_close_dashboard_internal() {
|
|||||||
|
|
||||||
pub async fn quit() {
|
pub async fn quit() {
|
||||||
logging!(debug, Type::System, true, "启动退出流程");
|
logging!(debug, Type::System, true, "启动退出流程");
|
||||||
|
utils::server::shutdown_embedded_server();
|
||||||
|
|
||||||
// 获取应用句柄并设置退出标志
|
// 获取应用句柄并设置退出标志
|
||||||
let app_handle = handle::Handle::app_handle();
|
let app_handle = handle::Handle::app_handle();
|
||||||
|
|||||||
@@ -6,7 +6,10 @@ use crate::{
|
|||||||
utils::logging::Type,
|
utils::logging::Type,
|
||||||
};
|
};
|
||||||
use anyhow::{Result, bail};
|
use anyhow::{Result, bail};
|
||||||
|
use once_cell::sync::OnceCell;
|
||||||
|
use parking_lot::Mutex;
|
||||||
use port_scanner::local_port_available;
|
use port_scanner::local_port_available;
|
||||||
|
use tokio::sync::oneshot;
|
||||||
use warp::Filter;
|
use warp::Filter;
|
||||||
|
|
||||||
#[derive(serde::Deserialize, Debug)]
|
#[derive(serde::Deserialize, Debug)]
|
||||||
@@ -14,6 +17,9 @@ struct QueryParam {
|
|||||||
param: String,
|
param: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 关闭 embedded server 的信号发送端
|
||||||
|
static SHUTDOWN_SENDER: OnceCell<Mutex<Option<oneshot::Sender<()>>>> = OnceCell::new();
|
||||||
|
|
||||||
/// check whether there is already exists
|
/// check whether there is already exists
|
||||||
pub async fn check_singleton() -> Result<()> {
|
pub async fn check_singleton() -> Result<()> {
|
||||||
let port = IVerge::get_singleton_port();
|
let port = IVerge::get_singleton_port();
|
||||||
@@ -42,6 +48,11 @@ pub async fn check_singleton() -> Result<()> {
|
|||||||
/// The embed server only be used to implement singleton process
|
/// The embed server only be used to implement singleton process
|
||||||
/// maybe it can be used as pac server later
|
/// maybe it can be used as pac server later
|
||||||
pub fn embed_server() {
|
pub fn embed_server() {
|
||||||
|
let (shutdown_tx, shutdown_rx) = oneshot::channel();
|
||||||
|
#[allow(clippy::expect_used)]
|
||||||
|
SHUTDOWN_SENDER
|
||||||
|
.set(Mutex::new(Some(shutdown_tx)))
|
||||||
|
.expect("failed to set shutdown signal for embedded server");
|
||||||
let port = IVerge::get_singleton_port();
|
let port = IVerge::get_singleton_port();
|
||||||
|
|
||||||
AsyncHandler::spawn(move || async move {
|
AsyncHandler::spawn(move || async move {
|
||||||
@@ -90,6 +101,22 @@ pub fn embed_server() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let commands = visible.or(scheme).or(pac);
|
let commands = visible.or(scheme).or(pac);
|
||||||
warp::serve(commands).run(([127, 0, 0, 1], port)).await;
|
warp::serve(commands)
|
||||||
|
.bind(([127, 0, 0, 1], port))
|
||||||
|
.await
|
||||||
|
.graceful(async {
|
||||||
|
shutdown_rx.await.ok();
|
||||||
|
})
|
||||||
|
.run()
|
||||||
|
.await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn shutdown_embedded_server() {
|
||||||
|
log::info!("shutting down embedded server");
|
||||||
|
if let Some(sender) = SHUTDOWN_SENDER.get()
|
||||||
|
&& let Some(sender) = sender.lock().take()
|
||||||
|
{
|
||||||
|
sender.send(()).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user