refactor: streamline SWR configuration and improve error handling in AppDataProvider
This commit is contained in:
125
src-tauri/src/core/manager/state.rs
Normal file
125
src-tauri/src/core/manager/state.rs
Normal file
@@ -0,0 +1,125 @@
|
||||
use super::{CoreManager, RunningMode};
|
||||
use crate::{
|
||||
AsyncHandler,
|
||||
config::Config,
|
||||
core::{
|
||||
handle,
|
||||
logger::ClashLogger,
|
||||
service,
|
||||
},
|
||||
logging,
|
||||
process::CommandChildGuard,
|
||||
utils::{
|
||||
dirs,
|
||||
init::sidecar_writer,
|
||||
logging::{SharedWriter, Type, write_sidecar_log},
|
||||
},
|
||||
};
|
||||
use anyhow::Result;
|
||||
use compact_str::CompactString;
|
||||
use flexi_logger::DeferredNow;
|
||||
use log::Level;
|
||||
use std::collections::VecDeque;
|
||||
use tauri_plugin_shell::ShellExt;
|
||||
|
||||
impl CoreManager {
|
||||
pub async fn get_clash_logs(&self) -> Result<VecDeque<CompactString>> {
|
||||
match self.get_running_mode() {
|
||||
RunningMode::Service => service::get_clash_logs_by_service().await,
|
||||
RunningMode::Sidecar => Ok(ClashLogger::global().get_logs().clone()),
|
||||
RunningMode::NotRunning => Ok(VecDeque::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) async fn start_core_by_sidecar(&self) -> Result<()> {
|
||||
logging!(info, Type::Core, "Starting core in sidecar mode");
|
||||
|
||||
let config_file = Config::generate_file(crate::config::ConfigType::Run).await?;
|
||||
let app_handle = handle::Handle::app_handle();
|
||||
let clash_core = Config::verge().await.latest_ref().get_valid_clash_core();
|
||||
let config_dir = dirs::app_home_dir()?;
|
||||
|
||||
let (mut rx, child) = app_handle
|
||||
.shell()
|
||||
.sidecar(&clash_core)?
|
||||
.args([
|
||||
"-d",
|
||||
dirs::path_to_str(&config_dir)?,
|
||||
"-f",
|
||||
dirs::path_to_str(&config_file)?,
|
||||
])
|
||||
.spawn()?;
|
||||
|
||||
let pid = child.pid();
|
||||
logging!(trace, Type::Core, "Sidecar started with PID: {}", pid);
|
||||
|
||||
{
|
||||
let mut state = self.state.lock();
|
||||
state.child_sidecar = Some(CommandChildGuard::new(child));
|
||||
state.running_mode = RunningMode::Sidecar;
|
||||
}
|
||||
|
||||
let shared_writer: SharedWriter = std::sync::Arc::new(tokio::sync::Mutex::new(sidecar_writer().await?));
|
||||
|
||||
AsyncHandler::spawn(|| async move {
|
||||
while let Some(event) = rx.recv().await {
|
||||
match event {
|
||||
tauri_plugin_shell::process::CommandEvent::Stdout(line)
|
||||
| tauri_plugin_shell::process::CommandEvent::Stderr(line) => {
|
||||
let mut now = DeferredNow::default();
|
||||
let message = CompactString::from(String::from_utf8_lossy(&line).as_ref());
|
||||
let w = shared_writer.lock().await;
|
||||
write_sidecar_log(w, &mut now, Level::Error, &message);
|
||||
ClashLogger::global().append_log(message);
|
||||
}
|
||||
tauri_plugin_shell::process::CommandEvent::Terminated(term) => {
|
||||
let mut now = DeferredNow::default();
|
||||
let message = if let Some(code) = term.code {
|
||||
CompactString::from(format!("Process terminated with code: {}", code))
|
||||
} else if let Some(signal) = term.signal {
|
||||
CompactString::from(format!("Process terminated by signal: {}", signal))
|
||||
} else {
|
||||
CompactString::from("Process terminated")
|
||||
};
|
||||
let w = shared_writer.lock().await;
|
||||
write_sidecar_log(w, &mut now, Level::Info, &message);
|
||||
ClashLogger::global().clear_logs();
|
||||
break;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn stop_core_by_sidecar(&self) -> Result<()> {
|
||||
logging!(info, Type::Core, "Stopping sidecar");
|
||||
|
||||
let mut state = self.state.lock();
|
||||
if let Some(child) = state.child_sidecar.take() {
|
||||
let pid = child.pid();
|
||||
drop(child);
|
||||
logging!(trace, Type::Core, "Sidecar stopped (PID: {:?})", pid);
|
||||
}
|
||||
state.running_mode = RunningMode::NotRunning;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) async fn start_core_by_service(&self) -> Result<()> {
|
||||
logging!(info, Type::Core, "Starting core in service mode");
|
||||
let config_file = Config::generate_file(crate::config::ConfigType::Run).await?;
|
||||
service::run_core_by_service(&config_file).await?;
|
||||
self.set_running_mode(RunningMode::Service);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) async fn stop_core_by_service(&self) -> Result<()> {
|
||||
logging!(info, Type::Core, "Stopping service");
|
||||
service::stop_core_by_service().await?;
|
||||
self.set_running_mode(RunningMode::NotRunning);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user