mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-27 08:38:58 +00:00
163 lines
4.7 KiB
Rust
163 lines
4.7 KiB
Rust
use std::{
|
|
collections::{HashMap, HashSet},
|
|
time::{SystemTime, UNIX_EPOCH},
|
|
};
|
|
|
|
use common::{
|
|
error::{Error, Result},
|
|
globals::GLOBAL_Local_Node_Name,
|
|
};
|
|
use protos::{
|
|
models::{PingBody, PingBodyBuilder},
|
|
node_service_time_out_client,
|
|
proto_gen::node_service::{PingRequest, PingResponse},
|
|
};
|
|
use serde::{Deserialize, Serialize};
|
|
use tonic::Request;
|
|
|
|
use crate::{disk::endpoint::Endpoint, global::GLOBAL_Endpoints, new_object_layer_fn, store_api::StorageAPI};
|
|
|
|
pub const ITEM_OFFLINE: &str = "offline";
|
|
pub const ITEM_INITIALIZING: &str = "initializing";
|
|
pub const ITEM_ONLINE: &str = "online";
|
|
|
|
#[derive(Debug, Default, Serialize, Deserialize)]
|
|
pub struct MemStats {
|
|
alloc: u64,
|
|
total_alloc: u64,
|
|
mallocs: u64,
|
|
frees: u64,
|
|
heap_alloc: u64,
|
|
}
|
|
|
|
#[derive(Debug, Default, Serialize, Deserialize)]
|
|
pub struct ServerProperties {
|
|
pub state: String,
|
|
pub endpoint: String,
|
|
pub scheme: String,
|
|
pub uptime: u64,
|
|
pub version: String,
|
|
pub commit_id: String,
|
|
pub network: HashMap<String, String>,
|
|
pub disks: Vec<madmin::Disk>,
|
|
pub pool_number: i32,
|
|
pub pool_numbers: Vec<i32>,
|
|
pub mem_stats: MemStats,
|
|
pub max_procs: u64,
|
|
pub num_cpu: u64,
|
|
pub runtime_version: String,
|
|
pub rustfs_env_vars: HashMap<String, String>,
|
|
}
|
|
|
|
async fn is_server_resolvable(endpoint: &Endpoint) -> Result<()> {
|
|
let addr = format!(
|
|
"{}://{}:{}",
|
|
endpoint.url.scheme(),
|
|
endpoint.url.host_str().unwrap(),
|
|
endpoint.url.port().unwrap()
|
|
);
|
|
let mut fbb = flatbuffers::FlatBufferBuilder::new();
|
|
let payload = fbb.create_vector(b"hello world");
|
|
|
|
let mut builder = PingBodyBuilder::new(&mut fbb);
|
|
builder.add_payload(payload);
|
|
let root = builder.finish();
|
|
fbb.finish(root, None);
|
|
|
|
let finished_data = fbb.finished_data();
|
|
|
|
let decoded_payload = flatbuffers::root::<PingBody>(finished_data);
|
|
assert!(decoded_payload.is_ok());
|
|
|
|
// 创建客户端
|
|
let mut client = node_service_time_out_client(&addr)
|
|
.await
|
|
.map_err(|err| Error::msg(err.to_string()))?;
|
|
|
|
// 构造 PingRequest
|
|
let request = Request::new(PingRequest {
|
|
version: 1,
|
|
body: finished_data.to_vec(),
|
|
});
|
|
|
|
// 发送请求并获取响应
|
|
let response: PingResponse = client.ping(request).await?.into_inner();
|
|
|
|
// 打印响应
|
|
let ping_response_body = flatbuffers::root::<PingBody>(&response.body);
|
|
if let Err(e) = ping_response_body {
|
|
eprintln!("{}", e);
|
|
} else {
|
|
println!("ping_resp:body(flatbuffer): {:?}", ping_response_body);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn get_local_server_property() -> ServerProperties {
|
|
let addr = GLOBAL_Local_Node_Name.read().await.clone();
|
|
let mut pool_numbers = HashSet::new();
|
|
let mut network = HashMap::new();
|
|
|
|
let endpoints = match GLOBAL_Endpoints.get() {
|
|
Some(eps) => eps,
|
|
None => return ServerProperties::default(),
|
|
};
|
|
for ep in endpoints.as_ref().iter() {
|
|
for endpoint in ep.endpoints.as_ref().iter() {
|
|
let node_name = match endpoint.url.host_str() {
|
|
Some(s) => s.to_string(),
|
|
None => addr.clone(),
|
|
};
|
|
if endpoint.is_local {
|
|
pool_numbers.insert(endpoint.pool_idx + 1);
|
|
network.insert(node_name, ITEM_ONLINE.to_string());
|
|
continue;
|
|
}
|
|
if let std::collections::hash_map::Entry::Vacant(e) = network.entry(node_name) {
|
|
if is_server_resolvable(endpoint).await.is_err() {
|
|
e.insert(ITEM_OFFLINE.to_string());
|
|
} else {
|
|
e.insert(ITEM_ONLINE.to_string());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// todo: mem collect
|
|
// let mem_stats =
|
|
|
|
let mut props = ServerProperties {
|
|
endpoint: addr,
|
|
uptime: SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(),
|
|
network,
|
|
..Default::default()
|
|
};
|
|
|
|
for pool_num in pool_numbers.iter() {
|
|
props.pool_numbers.push(*pool_num);
|
|
}
|
|
props.pool_numbers.sort();
|
|
props.pool_number = if props.pool_numbers.len() == 1 {
|
|
props.pool_numbers[1]
|
|
} else {
|
|
i32::MAX
|
|
};
|
|
|
|
// let mut sensitive = HashSet::new();
|
|
// sensitive.insert(ENV_ACCESS_KEY.to_string());
|
|
// sensitive.insert(ENV_SECRET_KEY.to_string());
|
|
// sensitive.insert(ENV_ROOT_USER.to_string());
|
|
// sensitive.insert(ENV_ROOT_PASSWORD.to_string());
|
|
|
|
if let Some(store) = new_object_layer_fn() {
|
|
let storage_info = store.local_storage_info().await;
|
|
props.state = ITEM_ONLINE.to_string();
|
|
props.disks = storage_info.disks;
|
|
} else {
|
|
props.state = ITEM_INITIALIZING.to_string();
|
|
};
|
|
|
|
props
|
|
}
|