mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-07 18:24:36 +00:00
refactor(rpc): Centralize RPC service and unify API (#1427)
This change introduces a major refactoring of the RPC service layer to improve modularity, unify the API, and simplify the overall architecture. Key changes: - Replaced per-network-instance RPC services with a single global RPC server, reducing resource usage and simplifying management. - All clients (CLI, Web UI, etc.) now interact with EasyTier core through a unified RPC entrypoint, enabling consistent authentication and control. - RPC implementation logic has been moved to `easytier/src/rpc_service/` and organized by functionality (e.g., `instance_manage.rs`, `peer_manage.rs`, `config.rs`) for better maintainability. - Standardized Protobuf API definitions under `easytier/src/proto/` with an `api_` prefix (e.g., `cli.proto` → `api_instance.proto`) to provide a consistent interface. - CLI commands now require explicit `--instance-id` or `--instance-name` when multiple network instances are running; the parameter is optional when only one instance exists. BREAKING CHANGE: RPC portal configuration (`rpc_portal` and `rpc_portal_whitelist`) has been removed from per-instance configs and the Web UI. The RPC listen address must now be specified globally via the `--rpc-portal` command-line flag or the `ET_RPC_PORTAL` environment variable, as there is only one RPC service for the entire application.
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
use std::sync::{mpsc::Sender, Mutex, OnceLock};
|
||||
|
||||
use crate::proto::{
|
||||
api::logger::{
|
||||
GetLoggerConfigRequest, GetLoggerConfigResponse, LogLevel, LoggerRpc,
|
||||
SetLoggerConfigRequest, SetLoggerConfigResponse,
|
||||
},
|
||||
rpc_types::{self, controller::BaseController},
|
||||
};
|
||||
|
||||
pub static LOGGER_LEVEL_SENDER: std::sync::OnceLock<Mutex<Sender<String>>> = OnceLock::new();
|
||||
pub static CURRENT_LOG_LEVEL: std::sync::OnceLock<Mutex<String>> = OnceLock::new();
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct LoggerRpcService;
|
||||
|
||||
impl LoggerRpcService {
|
||||
fn log_level_to_string(level: LogLevel) -> String {
|
||||
match level {
|
||||
LogLevel::Disabled => "off".to_string(),
|
||||
LogLevel::Error => "error".to_string(),
|
||||
LogLevel::Warning => "warn".to_string(),
|
||||
LogLevel::Info => "info".to_string(),
|
||||
LogLevel::Debug => "debug".to_string(),
|
||||
LogLevel::Trace => "trace".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
fn string_to_log_level(level_str: &str) -> LogLevel {
|
||||
match level_str.to_lowercase().as_str() {
|
||||
"off" | "disabled" => LogLevel::Disabled,
|
||||
"error" => LogLevel::Error,
|
||||
"warn" | "warning" => LogLevel::Warning,
|
||||
"info" => LogLevel::Info,
|
||||
"debug" => LogLevel::Debug,
|
||||
"trace" => LogLevel::Trace,
|
||||
_ => LogLevel::Info, // 默认为 Info 级别
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl LoggerRpc for LoggerRpcService {
|
||||
type Controller = BaseController;
|
||||
|
||||
async fn set_logger_config(
|
||||
&self,
|
||||
_: BaseController,
|
||||
request: SetLoggerConfigRequest,
|
||||
) -> Result<SetLoggerConfigResponse, rpc_types::error::Error> {
|
||||
let level_str = Self::log_level_to_string(request.level());
|
||||
|
||||
// 更新当前日志级别
|
||||
if let Some(current_level) = CURRENT_LOG_LEVEL.get() {
|
||||
if let Ok(mut level) = current_level.lock() {
|
||||
*level = level_str.clone();
|
||||
}
|
||||
}
|
||||
|
||||
// 发送新的日志级别到 logger 重载器
|
||||
if let Some(sender) = LOGGER_LEVEL_SENDER.get() {
|
||||
if let Ok(sender) = sender.lock() {
|
||||
if let Err(e) = sender.send(level_str) {
|
||||
tracing::warn!("Failed to send new log level to reloader: {}", e);
|
||||
return Err(rpc_types::error::Error::ExecutionError(anyhow::anyhow!(
|
||||
"Failed to update log level: {}",
|
||||
e
|
||||
)));
|
||||
}
|
||||
} else {
|
||||
return Err(rpc_types::error::Error::ExecutionError(anyhow::anyhow!(
|
||||
"Logger sender is not available"
|
||||
)));
|
||||
}
|
||||
} else {
|
||||
return Err(rpc_types::error::Error::ExecutionError(anyhow::anyhow!(
|
||||
"Logger reloader is not initialized"
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(SetLoggerConfigResponse {})
|
||||
}
|
||||
|
||||
async fn get_logger_config(
|
||||
&self,
|
||||
_: BaseController,
|
||||
_request: GetLoggerConfigRequest,
|
||||
) -> Result<GetLoggerConfigResponse, rpc_types::error::Error> {
|
||||
let current_level_str = if let Some(current_level) = CURRENT_LOG_LEVEL.get() {
|
||||
if let Ok(level) = current_level.lock() {
|
||||
level.clone()
|
||||
} else {
|
||||
"info".to_string() // 默认级别
|
||||
}
|
||||
} else {
|
||||
"info".to_string() // 默认级别
|
||||
};
|
||||
|
||||
let level = Self::string_to_log_level(¤t_level_str);
|
||||
|
||||
Ok(GetLoggerConfigResponse {
|
||||
level: level.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user