refactor: mutex

This commit is contained in:
GyDi 2022-04-19 14:38:59 +08:00 committed by GitHub
parent fac437b8c1
commit 3076fd19c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 105 additions and 99 deletions

1
src-tauri/Cargo.lock generated
View File

@ -489,6 +489,7 @@ dependencies = [
"log4rs", "log4rs",
"nanoid", "nanoid",
"open", "open",
"parking_lot 0.12.0",
"port_scanner", "port_scanner",
"reqwest", "reqwest",
"serde", "serde",

View File

@ -22,6 +22,7 @@ chrono = "0.4.19"
serde_json = "1.0" serde_json = "1.0"
serde_yaml = "0.8" serde_yaml = "0.8"
delay_timer = "0.11.1" delay_timer = "0.11.1"
parking_lot = "0.12.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.0.0-rc.6", features = ["process-all", "shell-all", "system-tray", "updater", "window-all"] } tauri = { version = "1.0.0-rc.6", features = ["process-all", "shell-all", "system-tray", "updater", "window-all"] }
window-shadows = { git = "https://github.com/tauri-apps/window-shadows" } window-shadows = { git = "https://github.com/tauri-apps/window-shadows" }

View File

@ -13,14 +13,14 @@ type CmdResult<T = ()> = Result<T, String>;
/// get all profiles from `profiles.yaml` /// get all profiles from `profiles.yaml`
#[tauri::command] #[tauri::command]
pub fn get_profiles(core: State<'_, Core>) -> CmdResult<Profiles> { pub fn get_profiles(core: State<'_, Core>) -> CmdResult<Profiles> {
let profiles = core.profiles.lock().unwrap(); let profiles = core.profiles.lock();
Ok(profiles.clone()) Ok(profiles.clone())
} }
/// synchronize data irregularly /// synchronize data irregularly
#[tauri::command] #[tauri::command]
pub fn sync_profiles(core: State<'_, Core>) -> CmdResult { pub fn sync_profiles(core: State<'_, Core>) -> CmdResult {
let mut profiles = core.profiles.lock().unwrap(); let mut profiles = core.profiles.lock();
wrap_err!(profiles.sync_file()) wrap_err!(profiles.sync_file())
} }
@ -34,7 +34,7 @@ pub async fn import_profile(
) -> CmdResult { ) -> CmdResult {
let item = wrap_err!(PrfItem::from_url(&url, None, None, option).await)?; let item = wrap_err!(PrfItem::from_url(&url, None, None, option).await)?;
let mut profiles = core.profiles.lock().unwrap(); let mut profiles = core.profiles.lock();
wrap_err!(profiles.append_item(item)) wrap_err!(profiles.append_item(item))
} }
@ -49,7 +49,7 @@ pub async fn create_profile(
) -> CmdResult { ) -> CmdResult {
let item = wrap_err!(PrfItem::from(item, file_data).await)?; let item = wrap_err!(PrfItem::from(item, file_data).await)?;
let mut profiles = core.profiles.lock().unwrap(); let mut profiles = core.profiles.lock();
wrap_err!(profiles.append_item(item)) wrap_err!(profiles.append_item(item))
} }
@ -62,7 +62,7 @@ pub async fn update_profile(
) -> CmdResult { ) -> CmdResult {
let (url, opt) = { let (url, opt) = {
// must release the lock here // must release the lock here
let profiles = core.profiles.lock().unwrap(); let profiles = core.profiles.lock();
let item = wrap_err!(profiles.get_item(&index))?; let item = wrap_err!(profiles.get_item(&index))?;
// check the profile type // check the profile type
@ -82,12 +82,13 @@ pub async fn update_profile(
let fetch_opt = PrfOption::merge(opt, option); let fetch_opt = PrfOption::merge(opt, option);
let item = wrap_err!(PrfItem::from_url(&url, None, None, fetch_opt).await)?; let item = wrap_err!(PrfItem::from_url(&url, None, None, fetch_opt).await)?;
let mut profiles = core.profiles.lock().unwrap(); let mut profiles = core.profiles.lock();
wrap_err!(profiles.update_item(index.clone(), item))?; wrap_err!(profiles.update_item(index.clone(), item))?;
// reactivate the profile // reactivate the profile
if Some(index) == profiles.get_current() { if Some(index) == profiles.get_current() {
log_if_err!(core.activate_enhanced(false, false)); drop(profiles);
log_if_err!(core.activate_enhanced(false));
} }
Ok(()) Ok(())
@ -96,12 +97,12 @@ pub async fn update_profile(
/// change the current profile /// change the current profile
#[tauri::command] #[tauri::command]
pub fn select_profile(index: String, core: State<'_, Core>) -> CmdResult { pub fn select_profile(index: String, core: State<'_, Core>) -> CmdResult {
{ let mut profiles = core.profiles.lock();
let mut profiles = core.profiles.lock().unwrap();
wrap_err!(profiles.put_current(index))?; wrap_err!(profiles.put_current(index))?;
}
log_if_err!(core.activate_enhanced(false, false)); drop(profiles);
log_if_err!(core.activate_enhanced(false));
Ok(()) Ok(())
} }
@ -109,12 +110,13 @@ pub fn select_profile(index: String, core: State<'_, Core>) -> CmdResult {
/// change the profile chain /// change the profile chain
#[tauri::command] #[tauri::command]
pub fn change_profile_chain(chain: Option<Vec<String>>, core: State<'_, Core>) -> CmdResult { pub fn change_profile_chain(chain: Option<Vec<String>>, core: State<'_, Core>) -> CmdResult {
{ dbg!("change profile chain");
let mut profiles = core.profiles.lock().unwrap(); let mut profiles = core.profiles.lock();
profiles.put_chain(chain); profiles.put_chain(chain);
} dbg!("change profile chain finish");
drop(profiles);
log_if_err!(core.activate_enhanced(false, false)); log_if_err!(core.activate_enhanced(false));
Ok(()) Ok(())
} }
@ -122,10 +124,11 @@ pub fn change_profile_chain(chain: Option<Vec<String>>, core: State<'_, Core>) -
/// change the profile valid fields /// change the profile valid fields
#[tauri::command] #[tauri::command]
pub fn change_profile_valid(valid: Option<Vec<String>>, core: State<Core>) -> CmdResult { pub fn change_profile_valid(valid: Option<Vec<String>>, core: State<Core>) -> CmdResult {
let mut profiles = core.profiles.lock().unwrap(); let mut profiles = core.profiles.lock();
profiles.put_valid(valid); profiles.put_valid(valid);
drop(profiles);
log_if_err!(core.activate_enhanced(false, false)); log_if_err!(core.activate_enhanced(false));
Ok(()) Ok(())
} }
@ -133,17 +136,19 @@ pub fn change_profile_valid(valid: Option<Vec<String>>, core: State<Core>) -> Cm
/// manually exec enhanced profile /// manually exec enhanced profile
#[tauri::command] #[tauri::command]
pub fn enhance_profiles(core: State<'_, Core>) -> CmdResult { pub fn enhance_profiles(core: State<'_, Core>) -> CmdResult {
log_if_err!(core.activate_enhanced(false, false)); log_if_err!(core.activate_enhanced(false));
Ok(()) Ok(())
} }
/// delete profile item /// delete profile item
#[tauri::command] #[tauri::command]
pub fn delete_profile(index: String, core: State<'_, Core>) -> CmdResult { pub fn delete_profile(index: String, core: State<'_, Core>) -> CmdResult {
let mut profiles = core.profiles.lock().unwrap(); let mut profiles = core.profiles.lock();
if wrap_err!(profiles.delete_item(index))? { if wrap_err!(profiles.delete_item(index))? {
log_if_err!(core.activate_enhanced(false, false)); drop(profiles);
// std::mem::drop(profiles);
log_if_err!(core.activate_enhanced(false));
} }
Ok(()) Ok(())
@ -152,7 +157,7 @@ pub fn delete_profile(index: String, core: State<'_, Core>) -> CmdResult {
/// patch the profile config /// patch the profile config
#[tauri::command] #[tauri::command]
pub fn patch_profile(index: String, profile: PrfItem, core: State<'_, Core>) -> CmdResult { pub fn patch_profile(index: String, profile: PrfItem, core: State<'_, Core>) -> CmdResult {
let mut profiles = core.profiles.lock().unwrap(); let mut profiles = core.profiles.lock();
wrap_err!(profiles.patch_item(index, profile)) wrap_err!(profiles.patch_item(index, profile))
} }
@ -160,7 +165,7 @@ pub fn patch_profile(index: String, profile: PrfItem, core: State<'_, Core>) ->
/// run vscode command to edit the profile /// run vscode command to edit the profile
#[tauri::command] #[tauri::command]
pub fn view_profile(index: String, core: State<'_, Core>) -> CmdResult { pub fn view_profile(index: String, core: State<'_, Core>) -> CmdResult {
let mut profiles = core.profiles.lock().unwrap(); let profiles = core.profiles.lock();
let item = wrap_err!(profiles.get_item(&index))?; let item = wrap_err!(profiles.get_item(&index))?;
let file = item.file.clone(); let file = item.file.clone();
@ -204,7 +209,7 @@ pub fn view_profile(index: String, core: State<'_, Core>) -> CmdResult {
/// read the profile item file data /// read the profile item file data
#[tauri::command] #[tauri::command]
pub fn read_profile_file(index: String, core: State<'_, Core>) -> CmdResult<String> { pub fn read_profile_file(index: String, core: State<'_, Core>) -> CmdResult<String> {
let mut profiles = core.profiles.lock().unwrap(); let profiles = core.profiles.lock();
let item = wrap_err!(profiles.get_item(&index))?; let item = wrap_err!(profiles.get_item(&index))?;
let data = wrap_err!(item.read_file())?; let data = wrap_err!(item.read_file())?;
@ -223,7 +228,7 @@ pub fn save_profile_file(
return Ok(()); return Ok(());
} }
let mut profiles = core.profiles.lock().unwrap(); let profiles = core.profiles.lock();
let item = wrap_err!(profiles.get_item(&index))?; let item = wrap_err!(profiles.get_item(&index))?;
wrap_err!(item.save_file(file_data.unwrap())) wrap_err!(item.save_file(file_data.unwrap()))
} }
@ -231,22 +236,14 @@ pub fn save_profile_file(
/// restart the sidecar /// restart the sidecar
#[tauri::command] #[tauri::command]
pub fn restart_sidecar(core: State<'_, Core>) -> CmdResult { pub fn restart_sidecar(core: State<'_, Core>) -> CmdResult {
let mut service = core.service.lock().unwrap(); wrap_err!(core.restart_clash())
wrap_err!(service.restart())?;
// 更新配置
log_if_err!(core.activate_enhanced(false, false));
Ok(())
} }
/// get the clash core info from the state /// get the clash core info from the state
/// the caller can also get the infomation by clash's api /// the caller can also get the infomation by clash's api
#[tauri::command] #[tauri::command]
pub fn get_clash_info(core: State<'_, Core>) -> CmdResult<ClashInfo> { pub fn get_clash_info(core: State<'_, Core>) -> CmdResult<ClashInfo> {
let clash = core.clash.lock().unwrap(); let clash = core.clash.lock();
Ok(clash.info.clone()) Ok(clash.info.clone())
} }
@ -268,14 +265,14 @@ pub fn get_sys_proxy() -> Result<SysProxyConfig, String> {
/// which may not the same as system proxy /// which may not the same as system proxy
#[tauri::command] #[tauri::command]
pub fn get_cur_proxy(core: State<'_, Core>) -> CmdResult<Option<SysProxyConfig>> { pub fn get_cur_proxy(core: State<'_, Core>) -> CmdResult<Option<SysProxyConfig>> {
let verge = core.verge.lock().unwrap(); let verge = core.verge.lock();
Ok(verge.cur_sysproxy.clone()) Ok(verge.cur_sysproxy.clone())
} }
/// get the verge config /// get the verge config
#[tauri::command] #[tauri::command]
pub fn get_verge_config(core: State<'_, Core>) -> CmdResult<VergeConfig> { pub fn get_verge_config(core: State<'_, Core>) -> CmdResult<VergeConfig> {
let verge = core.verge.lock().unwrap(); let verge = core.verge.lock();
let mut config = verge.config.clone(); let mut config = verge.config.clone();
if config.system_proxy_bypass.is_none() && verge.cur_sysproxy.is_some() { if config.system_proxy_bypass.is_none() && verge.cur_sysproxy.is_some() {
@ -296,9 +293,14 @@ pub fn patch_verge_config(
let tun_mode = payload.enable_tun_mode.clone(); let tun_mode = payload.enable_tun_mode.clone();
let system_proxy = payload.enable_system_proxy.clone(); let system_proxy = payload.enable_system_proxy.clone();
let mut verge = core.verge.lock().unwrap(); let mut verge = core.verge.lock();
wrap_err!(verge.patch_config(payload))?; wrap_err!(verge.patch_config(payload))?;
// change system tray
if system_proxy.is_some() || tun_mode.is_some() {
verge.update_systray(&app_handle).unwrap();
}
// change tun mode // change tun mode
if tun_mode.is_some() { if tun_mode.is_some() {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
@ -310,14 +312,8 @@ pub fn patch_verge_config(
} }
} }
let profiles = core.profiles.lock().unwrap(); std::mem::drop(verge);
log_if_err!(core.activate_enhanced(false));
log_if_err!(core.activate_enhanced(false, false));
}
// change system tray
if system_proxy.is_some() || tun_mode.is_some() {
verge.update_systray(&app_handle).unwrap();
} }
Ok(()) Ok(())

View File

@ -2,10 +2,11 @@ use self::notice::Notice;
use self::service::Service; use self::service::Service;
use crate::core::enhance::PrfEnhancedResult; use crate::core::enhance::PrfEnhancedResult;
use crate::log_if_err; use crate::log_if_err;
use crate::utils::{config, dirs, help}; use crate::utils::help;
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use parking_lot::Mutex;
use serde_yaml::Mapping; use serde_yaml::Mapping;
use std::sync::{Arc, Mutex}; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use tauri::Window; use tauri::Window;
use tokio::time::sleep; use tokio::time::sleep;
@ -53,58 +54,76 @@ impl Core {
} }
} }
pub fn init(&self) { pub fn init(&self, app_handle: tauri::AppHandle) {
log_if_err!(self.restart_clash()); let mut service = self.service.lock();
log_if_err!(service.start());
drop(service);
log_if_err!(self.activate());
let clash = self.clash.lock();
let mut verge = self.verge.lock();
let hide = verge.config.enable_silent_start.clone().unwrap_or(false);
// silent start
if hide {
let window = self.window.lock();
window.as_ref().map(|win| {
win.hide().unwrap();
});
}
let clash = self.clash.lock().unwrap();
let mut verge = self.verge.lock().unwrap();
verge.init_sysproxy(clash.info.port.clone()); verge.init_sysproxy(clash.info.port.clone());
log_if_err!(verge.init_launch()); log_if_err!(verge.init_launch());
log_if_err!(verge.update_systray(&app_handle));
// system tray drop(clash);
// verge.config.enable_system_proxy.map(|enable| { drop(verge);
// log_if_err!(app
// .tray_handle() // wait the window setup during resolve app
// .get_item("system_proxy") let core = self.clone();
// .set_selected(enable)); tauri::async_runtime::spawn(async move {
// }); sleep(Duration::from_secs(2)).await;
log_if_err!(core.activate_enhanced(true));
});
} }
/// save the window instance /// save the window instance
pub fn set_win(&self, win: Option<Window>) { pub fn set_win(&self, win: Option<Window>) {
let mut window = self.window.lock().unwrap(); let mut window = self.window.lock();
*window = win; *window = win;
} }
/// restart the clash sidecar /// restart the clash sidecar
pub fn restart_clash(&self) -> Result<()> { pub fn restart_clash(&self) -> Result<()> {
{ let mut service = self.service.lock();
let mut service = self.service.lock().unwrap();
service.restart()?; service.restart()?;
} drop(service);
self.activate()?; self.activate()?;
self.activate_enhanced(false, true) self.activate_enhanced(true)
} }
/// handle the clash config changed /// handle the clash config changed
pub fn patch_clash(&self, patch: Mapping) -> Result<()> { pub fn patch_clash(&self, patch: Mapping) -> Result<()> {
let (changed, port) = { let (changed, port) = {
let mut clash = self.clash.lock().unwrap(); let mut clash = self.clash.lock();
(clash.patch_config(patch)?, clash.info.port.clone()) (clash.patch_config(patch)?, clash.info.port.clone())
}; };
// todo: port check // todo: port check
if changed { if changed {
let mut service = self.service.lock().unwrap(); let mut service = self.service.lock();
service.restart()?; service.restart()?;
drop(service);
self.activate()?; self.activate()?;
self.activate_enhanced(false, true)?; self.activate_enhanced(true)?;
let mut verge = self.verge.lock().unwrap(); let mut verge = self.verge.lock();
verge.init_sysproxy(port); verge.init_sysproxy(port);
} }
@ -115,13 +134,13 @@ impl Core {
/// auto activate enhanced profile /// auto activate enhanced profile
pub fn activate(&self) -> Result<()> { pub fn activate(&self) -> Result<()> {
let data = { let data = {
let profiles = self.profiles.lock().unwrap(); let profiles = self.profiles.lock();
let data = profiles.gen_activate()?; let data = profiles.gen_activate()?;
Clash::strict_filter(data) Clash::strict_filter(data)
}; };
let (mut config, info) = { let (mut config, info) = {
let clash = self.clash.lock().unwrap(); let clash = self.clash.lock();
let config = clash.config.clone(); let config = clash.config.clone();
let info = clash.info.clone(); let info = clash.info.clone();
(config, info) (config, info)
@ -132,23 +151,23 @@ impl Core {
} }
let config = { let config = {
let verge = self.verge.lock().unwrap(); let verge = self.verge.lock();
let tun_mode = verge.config.enable_tun_mode.unwrap_or(false); let tun_mode = verge.config.enable_tun_mode.unwrap_or(false);
Clash::_tun_mode(config, tun_mode) Clash::_tun_mode(config, tun_mode)
}; };
let notice = { let notice = {
let window = self.window.lock().unwrap(); let window = self.window.lock();
Notice::from(window.clone()) Notice::from(window.clone())
}; };
let service = self.service.lock().unwrap(); let service = self.service.lock();
service.set_config(info, config, notice) service.set_config(info, config, notice)
} }
/// enhanced profiles mode /// enhanced profiles mode
pub fn activate_enhanced(&self, delay: bool, skip: bool) -> Result<()> { pub fn activate_enhanced(&self, skip: bool) -> Result<()> {
let window = self.window.lock().unwrap(); let window = self.window.lock();
if window.is_none() { if window.is_none() {
bail!("failed to get the main window"); bail!("failed to get the main window");
} }
@ -158,7 +177,7 @@ impl Core {
// generate the payload // generate the payload
let payload = { let payload = {
let profiles = self.profiles.lock().unwrap(); let profiles = self.profiles.lock();
profiles.gen_enhanced(event_name.clone())? profiles.gen_enhanced(event_name.clone())?
}; };
@ -168,16 +187,17 @@ impl Core {
return Ok(()); return Ok(());
} }
drop(window);
return self.activate(); return self.activate();
} }
let tun_mode = { let tun_mode = {
let verge = self.verge.lock().unwrap(); let verge = self.verge.lock();
verge.config.enable_tun_mode.unwrap_or(false) verge.config.enable_tun_mode.unwrap_or(false)
}; };
let info = { let info = {
let clash = self.clash.lock().unwrap(); let clash = self.clash.lock();
clash.info.clone() clash.info.clone()
}; };
@ -206,7 +226,7 @@ impl Core {
let config = Clash::_tun_mode(config, tun_mode); let config = Clash::_tun_mode(config, tun_mode);
let service = service.lock().unwrap(); let service = service.lock();
log_if_err!(service.set_config(info, config, notice)); log_if_err!(service.set_config(info, config, notice));
log::info!("profile enhanced status {}", result.status); log::info!("profile enhanced status {}", result.status);
@ -215,7 +235,6 @@ impl Core {
result.error.map(|err| log::error!("{err}")); result.error.map(|err| log::error!("{err}"));
}); });
// wait the window setup during resolve app
// if delay { // if delay {
// sleep(Duration::from_secs(2)).await; // sleep(Duration::from_secs(2)).await;
// } // }

View File

@ -51,7 +51,7 @@ fn main() -> std::io::Result<()> {
} }
"system_proxy" => { "system_proxy" => {
let core = app_handle.state::<core::Core>(); let core = app_handle.state::<core::Core>();
let mut verge = core.verge.lock().unwrap(); let mut verge = core.verge.lock();
let old_value = verge.config.enable_system_proxy.clone().unwrap_or(false); let old_value = verge.config.enable_system_proxy.clone().unwrap_or(false);
let new_value = !old_value; let new_value = !old_value;
@ -66,7 +66,7 @@ fn main() -> std::io::Result<()> {
} }
"tun_mode" => { "tun_mode" => {
let core = app_handle.state::<core::Core>(); let core = app_handle.state::<core::Core>();
let mut verge = core.verge.lock().unwrap(); let mut verge = core.verge.lock();
let old_value = verge.config.enable_tun_mode.clone().unwrap_or(false); let old_value = verge.config.enable_tun_mode.clone().unwrap_or(false);
let new_value = !old_value; let new_value = !old_value;

View File

@ -1,4 +1,3 @@
use crate::log_if_err;
use crate::{core::Core, utils::init, utils::server}; use crate::{core::Core, utils::init, utils::server};
use tauri::{App, AppHandle, Manager}; use tauri::{App, AppHandle, Manager};
@ -14,33 +13,23 @@ pub fn resolve_setup(app: &App) {
let core = app.state::<Core>(); let core = app.state::<Core>();
core.set_win(app.get_window("main")); core.set_win(app.get_window("main"));
core.init(); core.init(app.app_handle());
// clash.set_window(app.get_window("main")); resolve_window(app);
// log_if_err!(clash.run_sidecar(&profiles, true));
resolve_window(app, None);
} }
/// reset system proxy /// reset system proxy
pub fn resolve_reset(app_handle: &AppHandle) { pub fn resolve_reset(app_handle: &AppHandle) {
let core = app_handle.state::<Core>(); let core = app_handle.state::<Core>();
let mut verge = core.verge.lock().unwrap(); let mut verge = core.verge.lock();
verge.reset_sysproxy(); verge.reset_sysproxy();
} }
/// customize the window theme /// customize the window theme
fn resolve_window(app: &App, hide: Option<bool>) { fn resolve_window(app: &App) {
let window = app.get_window("main").unwrap(); let window = app.get_window("main").unwrap();
// silent start
hide.map(|hide| {
if hide {
window.hide().unwrap();
}
});
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
{ {
use window_shadows::set_shadow; use window_shadows::set_shadow;