1use std::{fmt::Debug, time::Duration};
16
17use anyhow::anyhow;
18
19use crate::{
20 buffer::manager::BUFFER_HEADER_SIZE,
21 consts::{DEFAULT_QUEUE_CAP, DEFAULT_SHARE_MEMORY_CAP, MemMapType, SESSION_REBUILD_INTERVAL},
22};
23
24#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
25pub struct SizePercentPair {
26 pub size: u32,
27 pub percent: u32,
28}
29
30#[derive(Clone, Debug)]
31pub struct Config {
33 pub connection_write_timeout: Duration,
38
39 pub connection_read_timeout: Option<Duration>,
40
41 pub connection_timeout: Option<Duration>,
42
43 pub initialize_timeout: Duration,
45
46 pub queue_cap: u32,
48
49 pub queue_path: String,
51
52 pub share_memory_buffer_cap: u32,
54
55 pub share_memory_path_prefix: String,
57
58 pub buffer_slice_sizes: Vec<SizePercentPair>,
60
61 pub mem_map_type: MemMapType,
63
64 pub rebuild_interval: Duration,
66
67 pub max_stream_num: usize,
68}
69
70impl Default for Config {
71 fn default() -> Self {
72 Self::new()
73 }
74}
75
76impl Config {
77 pub fn new() -> Self {
78 Self {
79 connection_write_timeout: Duration::from_secs(10),
80 connection_read_timeout: None,
81 connection_timeout: None,
82 initialize_timeout: Duration::from_millis(1000),
83 queue_cap: DEFAULT_QUEUE_CAP,
84 queue_path: "/dev/shm/shmipc_queue".to_owned(),
85 share_memory_buffer_cap: DEFAULT_SHARE_MEMORY_CAP,
86 share_memory_path_prefix: "/dev/shm/shmipc".to_owned(),
87 buffer_slice_sizes: vec![
88 SizePercentPair {
89 size: 8192 - BUFFER_HEADER_SIZE,
90 percent: 50,
91 },
92 SizePercentPair {
93 size: 32 * 1024 - BUFFER_HEADER_SIZE,
94 percent: 30,
95 },
96 SizePercentPair {
97 size: 128 * 1024 - BUFFER_HEADER_SIZE,
98 percent: 20,
99 },
100 ],
101 mem_map_type: MemMapType::MemMapTypeMemFd,
102 rebuild_interval: SESSION_REBUILD_INTERVAL,
103 max_stream_num: 4096,
104 }
105 }
106
107 pub fn verify(&self) -> Result<(), anyhow::Error> {
108 if self.share_memory_buffer_cap < (1 << 20) {
109 return Err(anyhow!(
110 "share memory size is too small:{}, must greater than {}",
111 self.share_memory_buffer_cap,
112 1 << 20
113 ));
114 }
115 if self.buffer_slice_sizes.is_empty() {
116 return Err(anyhow!("buffer_slice_sizes could not be nil"));
117 }
118
119 let mut sum = 0;
120 for pair in self.buffer_slice_sizes.iter() {
121 sum += pair.percent;
122 if pair.size > self.share_memory_buffer_cap {
123 return Err(anyhow!(
124 "buffer_slice_sizes's size:{} couldn't greater than share_memory_buffer_cap:{}",
125 pair.size,
126 self.share_memory_buffer_cap
127 ));
128 }
129
130 #[cfg(any(target_arch = "arm", target_arch = "arm64ec"))]
131 if pair.size % 4 != 0 {
132 return Err(anyhow!(
133 "the size_percent_pair.size must be a multiple of 4"
134 ));
135 }
136 }
137
138 if sum != 100 {
139 return Err(anyhow!(
140 "the sum of buffer_slice_sizes's percent should be 100",
141 ));
142 }
143
144 #[cfg(any(target_arch = "arm", target_arch = "arm64ec"))]
145 if self.queue_cap % 8 != 0 {
146 return Err(anyhow!("the queue_cap must be a multiple of 8"));
147 }
148
149 if self.share_memory_path_prefix.is_empty() || self.queue_path.is_empty() {
150 return Err(anyhow!("buffer path or queue path could not be nil"));
151 }
152
153 #[cfg(not(target_os = "linux"))]
154 {
155 return Err(anyhow!("shmipc just support linux OS now"));
156 }
157
158 #[cfg(not(any(target_arch = "x86_64", target_arch = "arm64ec")))]
159 {
160 return Err(anyhow!("shmipc just support amd64 or arm64 arch"));
161 }
162
163 Ok(())
164 }
165}