use std::{fmt::Debug, time::Duration};
use anyhow::anyhow;
use crate::consts::{
DEFAULT_BUFFER_SLICE_SIZES, DEFAULT_QUEUE_CAP, DEFAULT_QUEUE_PATH, DEFAULT_SHARE_MEMORY_CAP,
MemMapType, SESSION_REBUILD_INTERVAL,
};
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct SizePercentPair {
pub size: u32,
pub percent: u32,
}
#[derive(Debug, Clone)]
pub struct Config {
pub connection_write_timeout: Duration,
pub connection_read_timeout: Option<Duration>,
pub connection_timeout: Option<Duration>,
pub initialize_timeout: Duration,
pub queue_cap: u32,
pub queue_path: String,
pub share_memory_buffer_cap: u32,
pub share_memory_path_prefix: String,
pub buffer_slice_sizes: Vec<SizePercentPair>,
pub mem_map_type: MemMapType,
pub rebuild_interval: Duration,
pub max_stream_num: usize,
}
impl Default for Config {
fn default() -> Self {
Self {
connection_write_timeout: Duration::from_secs(10),
connection_read_timeout: None,
connection_timeout: None,
initialize_timeout: Duration::from_millis(1000),
queue_cap: DEFAULT_QUEUE_CAP,
queue_path: DEFAULT_QUEUE_PATH.to_owned(),
share_memory_buffer_cap: DEFAULT_SHARE_MEMORY_CAP,
share_memory_path_prefix: "/dev/shm/shmipc".to_owned(),
buffer_slice_sizes: DEFAULT_BUFFER_SLICE_SIZES.to_vec(),
mem_map_type: Default::default(),
rebuild_interval: SESSION_REBUILD_INTERVAL,
max_stream_num: 4096,
}
}
}
impl Config {
pub fn new() -> Self {
Self::default()
}
pub fn verify(&self) -> Result<(), anyhow::Error> {
if self.share_memory_buffer_cap < (1 << 20) {
return Err(anyhow!(
"share memory size is too small:{}, must greater than {}",
self.share_memory_buffer_cap,
1 << 20
));
}
if self.buffer_slice_sizes.is_empty() {
return Err(anyhow!("buffer_slice_sizes could not be nil"));
}
let mut sum = 0;
for pair in self.buffer_slice_sizes.iter() {
sum += pair.percent;
if pair.size > self.share_memory_buffer_cap {
return Err(anyhow!(
"buffer_slice_sizes's size:{} couldn't greater than share_memory_buffer_cap:{}",
pair.size,
self.share_memory_buffer_cap
));
}
#[cfg(target_arch = "aarch64")]
if pair.size % 4 != 0 {
return Err(anyhow!(
"the size_percent_pair.size must be a multiple of 4"
));
}
}
if sum != 100 {
return Err(anyhow!(
"the sum of buffer_slice_sizes's percent should be 100",
));
}
#[cfg(target_arch = "aarch64")]
if self.queue_cap % 8 != 0 {
return Err(anyhow!("the queue_cap must be a multiple of 8"));
}
if self.share_memory_path_prefix.is_empty() || self.queue_path.is_empty() {
return Err(anyhow!("buffer path or queue path could not be nil"));
}
#[cfg(not(target_os = "linux"))]
{
return Err(anyhow!("shmipc just support linux OS now"));
}
#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
{
return Err(anyhow!("shmipc just support amd64 or arm64 arch"));
}
Ok(())
}
}