Files
clash-verge-rev/src-tauri/src/core/manager/state.rs
T

129 lines
4.7 KiB
Rust

use super::{CoreManager, RunningMode};
use crate::{
AsyncHandler,
config::Config,
core::{handle, logger::CLASH_LOGGER, 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 scopeguard::defer;
use tauri_plugin_shell::ShellExt;
impl CoreManager {
pub async fn get_clash_logs(&self) -> Result<Vec<CompactString>> {
match *self.get_running_mode() {
RunningMode::Service => service::get_clash_logs_by_service().await,
RunningMode::Sidecar => Ok(CLASH_LOGGER.get_logs().await),
RunningMode::NotRunning => Ok(Vec::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_arc().get_valid_clash_core();
let config_dir = dirs::app_home_dir()?;
let (mut rx, child) = app_handle
.shell()
.sidecar(clash_core.as_str())?
.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);
self.set_running_child_sidecar(CommandChildGuard::new(child));
self.set_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());
write_sidecar_log(
shared_writer.lock().await,
&mut now,
Level::Error,
&message,
);
CLASH_LOGGER.append_log(message).await;
}
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")
};
write_sidecar_log(
shared_writer.lock().await,
&mut now,
Level::Info,
&message,
);
CLASH_LOGGER.clear_logs().await;
break;
}
_ => {}
}
}
});
Ok(())
}
pub(super) fn stop_core_by_sidecar(&self) -> Result<()> {
logging!(info, Type::Core, "Stopping sidecar");
defer! {
self.set_running_mode(RunningMode::NotRunning);
}
if let Some(child) = self.take_child_sidecar() {
let pid = child.pid();
drop(child);
logging!(trace, Type::Core, "Sidecar stopped (PID: {:?})", pid);
}
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");
defer! {
self.set_running_mode(RunningMode::NotRunning);
}
service::stop_core_by_service().await?;
Ok(())
}
}