use config::ConfigError;
use serde::Deserialize;
use serde::Serialize;
use crate::Error;
use crate::Result;
#[derive(Debug, Serialize, Deserialize, Clone)]
#[allow(dead_code)]
pub struct NetworkConfig {
#[serde(default = "default_control_params")]
pub control: ConnectionParams,
#[serde(default = "default_data_params")]
pub data: ConnectionParams,
#[serde(default = "default_bulk_params")]
pub bulk: ConnectionParams,
#[serde(default = "default_tcp_nodelay")]
pub tcp_nodelay: bool,
#[serde(default = "default_buffer_size")]
pub buffer_size: usize,
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
pub struct ConnectionParams {
#[serde(default = "default_connect_timeout")]
pub connect_timeout_in_ms: u64,
#[serde(default = "default_request_timeout")]
pub request_timeout_in_ms: u64,
#[serde(default = "default_concurrency_limit")]
pub concurrency_limit: usize,
#[serde(default = "default_max_streams")]
pub max_concurrent_streams: u32,
#[serde(default = "default_tcp_keepalive")]
pub tcp_keepalive_in_secs: u64,
#[serde(default = "default_h2_keepalive_interval")]
pub http2_keep_alive_interval_in_secs: u64,
#[serde(default = "default_h2_keepalive_timeout")]
pub http2_keep_alive_timeout_in_secs: u64,
#[serde(default = "default_max_frame_size")]
pub max_frame_size: u32,
#[serde(default = "default_conn_window_size")]
pub connection_window_size: u32,
#[serde(default = "default_stream_window_size")]
pub stream_window_size: u32,
#[serde(default = "default_adaptive_window")]
pub adaptive_window: bool,
}
impl Default for NetworkConfig {
fn default() -> Self {
Self {
control: default_control_params(),
data: default_data_params(),
bulk: default_bulk_params(),
tcp_nodelay: default_tcp_nodelay(),
buffer_size: default_buffer_size(),
}
}
}
impl NetworkConfig {
pub fn validate(&self) -> Result<()> {
if self.buffer_size < 1024 {
return Err(Error::Config(ConfigError::Message(format!(
"Buffer size {} too small, minimum 1024 bytes",
self.buffer_size
))));
}
self.control.validate("control")?;
self.data.validate("data")?;
self.bulk.validate("bulk")?;
Ok(())
}
}
impl ConnectionParams {
pub(crate) fn validate(
&self,
conn_type: &str,
) -> Result<()> {
if self.connect_timeout_in_ms == 0 {
return Err(Error::Config(ConfigError::Message(format!(
"{conn_type} connection timeout must be > 0",
))));
}
if self.request_timeout_in_ms != 0
&& self.request_timeout_in_ms <= self.connect_timeout_in_ms
{
return Err(Error::Config(ConfigError::Message(format!(
"{} request timeout {}ms must exceed connect timeout {}ms",
conn_type, self.request_timeout_in_ms, self.connect_timeout_in_ms
))));
}
if self.http2_keep_alive_timeout_in_secs >= self.http2_keep_alive_interval_in_secs {
return Err(Error::Config(ConfigError::Message(format!(
"{} keepalive timeout {}s must be < interval {}s",
conn_type,
self.http2_keep_alive_timeout_in_secs,
self.http2_keep_alive_interval_in_secs
))));
}
if !self.adaptive_window {
const MIN_WINDOW: u32 = 65535; if self.stream_window_size < MIN_WINDOW {
return Err(Error::Config(ConfigError::Message(format!(
"{} stream window size {} below minimum {}",
conn_type, self.stream_window_size, MIN_WINDOW
))));
}
if self.connection_window_size < self.stream_window_size {
return Err(Error::Config(ConfigError::Message(format!(
"{} connection window {} smaller than stream window {}",
conn_type, self.connection_window_size, self.stream_window_size
))));
}
}
Ok(())
}
}
fn default_control_params() -> ConnectionParams {
ConnectionParams {
connect_timeout_in_ms: 20, request_timeout_in_ms: 100, concurrency_limit: 1024, max_concurrent_streams: 100, tcp_keepalive_in_secs: 300, http2_keep_alive_interval_in_secs: 30, http2_keep_alive_timeout_in_secs: 5, max_frame_size: default_max_frame_size(),
connection_window_size: 1_048_576, stream_window_size: 262_144, adaptive_window: false, }
}
fn default_data_params() -> ConnectionParams {
ConnectionParams {
connect_timeout_in_ms: 50, request_timeout_in_ms: 500, concurrency_limit: 8192, max_concurrent_streams: 500, tcp_keepalive_in_secs: 600, http2_keep_alive_interval_in_secs: 120, http2_keep_alive_timeout_in_secs: 30, max_frame_size: default_max_frame_size(),
connection_window_size: 6_291_456, stream_window_size: 1_048_576, adaptive_window: true, }
}
fn default_bulk_params() -> ConnectionParams {
ConnectionParams {
connect_timeout_in_ms: 500000, request_timeout_in_ms: 5000000, concurrency_limit: 4, max_concurrent_streams: 2, tcp_keepalive_in_secs: 3600, http2_keep_alive_interval_in_secs: 600, http2_keep_alive_timeout_in_secs: 60, max_frame_size: 16_777_215, connection_window_size: 67_108_864, stream_window_size: 16_777_216, adaptive_window: false, }
}
fn default_connect_timeout() -> u64 {
20
}
fn default_request_timeout() -> u64 {
100
}
fn default_concurrency_limit() -> usize {
256
}
fn default_max_streams() -> u32 {
500
}
fn default_tcp_nodelay() -> bool {
true
}
fn default_tcp_keepalive() -> u64 {
3600
}
fn default_h2_keepalive_interval() -> u64 {
300
}
fn default_h2_keepalive_timeout() -> u64 {
20
}
fn default_max_frame_size() -> u32 {
16_777_215
}
fn default_conn_window_size() -> u32 {
20_971_520 }
fn default_stream_window_size() -> u32 {
10_485_760 }
fn default_buffer_size() -> usize {
65_536
}
fn default_adaptive_window() -> bool {
false
}