#[derive(Debug, Clone, Default)]
pub struct AdvancedConfig {
pub buffer_selection: bool,
pub multi_shot: bool,
pub provided_buffers: bool,
pub fast_poll: bool,
pub sq_poll: bool,
pub sq_thread_cpu: Option<u32>,
pub coop_taskrun: bool,
pub defer_taskrun: bool,
pub advanced_task_work: bool,
pub defer_async_work: bool,
pub send_zc_reporting: bool,
pub multishot_completion_batching: bool,
pub epoll_uring_wake: bool,
pub registered_ring_fd: bool,
pub multishot_timeouts: bool,
pub user_allocated_ring_memory: bool,
pub async_cancel_op: bool,
pub socket_command_support: bool,
pub direct_io_optimizations: bool,
pub msg_ring_speedup: bool,
pub native_bind_listen: bool,
pub improved_huge_pages: bool,
pub async_discard: bool,
pub minimum_timeout_waits: bool,
pub absolute_timeouts: bool,
pub incremental_buffer_consumption: bool,
pub registered_buffer_cloning: bool,
}
impl AdvancedConfig {
pub fn new() -> Self {
Self::default()
}
pub fn stable() -> Self {
Self {
buffer_selection: true,
fast_poll: true,
provided_buffers: true,
coop_taskrun: true,
defer_taskrun: true,
sq_poll: false,
defer_async_work: false,
user_allocated_ring_memory: false,
..Self::default()
}
}
pub fn performance() -> Self {
Self {
..Self::stable()
}
.with_multi_shot(true)
.with_advanced_task_work(true)
.with_send_zc_reporting(true)
.with_multishot_completion_batching(true)
.with_async_cancel_op(true)
.with_direct_io_optimizations(true)
}
pub fn development() -> Self {
Self {
buffer_selection: true,
multi_shot: true,
provided_buffers: true,
fast_poll: true,
coop_taskrun: true,
defer_taskrun: true,
sq_poll: false,
defer_async_work: false,
..Self::default()
}
}
pub fn with_buffer_selection(mut self, enabled: bool) -> Self {
self.buffer_selection = enabled;
self
}
pub fn with_multi_shot(mut self, enabled: bool) -> Self {
self.multi_shot = enabled;
self
}
pub fn with_provided_buffers(mut self, enabled: bool) -> Self {
self.provided_buffers = enabled;
self
}
pub fn with_fast_poll(mut self, enabled: bool) -> Self {
self.fast_poll = enabled;
self
}
pub fn with_sq_poll(mut self, enabled: bool, cpu: Option<u32>) -> Self {
self.sq_poll = enabled;
self.sq_thread_cpu = if enabled { cpu } else { None };
self
}
pub fn with_coop_taskrun(mut self, enabled: bool) -> Self {
self.coop_taskrun = enabled;
self
}
pub fn with_defer_taskrun(mut self, enabled: bool) -> Self {
self.defer_taskrun = enabled;
self
}
pub fn with_advanced_task_work(mut self, enabled: bool) -> Self {
self.advanced_task_work = enabled;
self
}
pub fn with_send_zc_reporting(mut self, enabled: bool) -> Self {
self.send_zc_reporting = enabled;
self
}
pub fn with_multishot_completion_batching(mut self, enabled: bool) -> Self {
self.multishot_completion_batching = enabled;
self
}
pub fn with_async_cancel_op(mut self, enabled: bool) -> Self {
self.async_cancel_op = enabled;
self
}
pub fn with_direct_io_optimizations(mut self, enabled: bool) -> Self {
self.direct_io_optimizations = enabled;
self
}
pub fn enabled_features(&self) -> Vec<&'static str> {
let mut features = Vec::new();
if self.buffer_selection {
features.push("buffer_selection");
}
if self.multi_shot {
features.push("multi_shot");
}
if self.provided_buffers {
features.push("provided_buffers");
}
if self.fast_poll {
features.push("fast_poll");
}
if self.sq_poll {
features.push("sq_poll");
}
if self.coop_taskrun {
features.push("coop_taskrun");
}
if self.defer_taskrun {
features.push("defer_taskrun");
}
if self.advanced_task_work {
features.push("advanced_task_work");
}
if self.defer_async_work {
features.push("defer_async_work");
}
if self.send_zc_reporting {
features.push("send_zc_reporting");
}
if self.multishot_completion_batching {
features.push("multishot_completion_batching");
}
if self.epoll_uring_wake {
features.push("epoll_uring_wake");
}
if self.registered_ring_fd {
features.push("registered_ring_fd");
}
if self.multishot_timeouts {
features.push("multishot_timeouts");
}
if self.user_allocated_ring_memory {
features.push("user_allocated_ring_memory");
}
if self.async_cancel_op {
features.push("async_cancel_op");
}
if self.socket_command_support {
features.push("socket_command_support");
}
if self.direct_io_optimizations {
features.push("direct_io_optimizations");
}
if self.msg_ring_speedup {
features.push("msg_ring_speedup");
}
if self.native_bind_listen {
features.push("native_bind_listen");
}
if self.improved_huge_pages {
features.push("improved_huge_pages");
}
if self.async_discard {
features.push("async_discard");
}
if self.minimum_timeout_waits {
features.push("minimum_timeout_waits");
}
if self.absolute_timeouts {
features.push("absolute_timeouts");
}
if self.incremental_buffer_consumption {
features.push("incremental_buffer_consumption");
}
if self.registered_buffer_cloning {
features.push("registered_buffer_cloning");
}
features
}
pub fn feature_count(&self) -> usize {
self.enabled_features().len()
}
pub fn validate(&self) -> Vec<String> {
let mut warnings = Vec::new();
if self.sq_poll && self.defer_taskrun {
warnings.push("sq_poll and defer_taskrun may conflict on some kernels".to_string());
}
if self.defer_async_work && !self.advanced_task_work {
warnings.push("defer_async_work requires advanced_task_work for stability".to_string());
}
if self.user_allocated_ring_memory {
warnings
.push("user_allocated_ring_memory requires custom memory management".to_string());
}
if self.sq_poll && self.sq_thread_cpu.is_none() {
warnings.push("sq_poll without CPU affinity may cause performance issues".to_string());
}
let intensive_features = [
self.sq_poll,
self.defer_async_work,
self.user_allocated_ring_memory,
];
if intensive_features.iter().filter(|&&x| x).count() > 1 {
warnings.push("Multiple resource-intensive features enabled".to_string());
}
warnings
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = AdvancedConfig::default();
assert!(!config.buffer_selection);
assert!(!config.multi_shot);
assert!(!config.provided_buffers);
assert!(!config.fast_poll);
assert!(!config.sq_poll);
assert!(config.sq_thread_cpu.is_none());
assert!(!config.coop_taskrun);
assert!(!config.defer_taskrun);
assert!(!config.advanced_task_work);
assert!(!config.defer_async_work);
assert!(!config.send_zc_reporting);
assert!(!config.multishot_completion_batching);
assert!(!config.epoll_uring_wake);
assert!(!config.registered_ring_fd);
assert!(!config.multishot_timeouts);
assert!(!config.user_allocated_ring_memory);
assert!(!config.async_cancel_op);
assert!(!config.socket_command_support);
assert!(!config.direct_io_optimizations);
assert!(!config.msg_ring_speedup);
assert!(!config.native_bind_listen);
assert!(!config.improved_huge_pages);
assert!(!config.async_discard);
assert!(!config.minimum_timeout_waits);
assert!(!config.absolute_timeouts);
assert!(!config.incremental_buffer_consumption);
assert!(!config.registered_buffer_cloning);
}
#[test]
fn test_new_config() {
let config = AdvancedConfig::new();
assert_eq!(
format!("{config:?}"),
format!("{:?}", AdvancedConfig::default())
);
}
#[test]
fn test_stable_config() {
let config = AdvancedConfig::stable();
assert!(config.buffer_selection);
assert!(config.fast_poll);
assert!(config.provided_buffers);
assert!(config.coop_taskrun);
assert!(config.defer_taskrun);
assert!(!config.sq_poll);
assert!(!config.defer_async_work);
assert!(!config.user_allocated_ring_memory);
}
#[test]
fn test_performance_config() {
let config = AdvancedConfig::performance();
assert!(config.buffer_selection);
assert!(config.fast_poll);
assert!(config.multi_shot);
assert!(config.advanced_task_work);
assert!(config.send_zc_reporting);
assert!(config.multishot_completion_batching);
}
#[test]
fn test_development_config() {
let config = AdvancedConfig::development();
assert!(config.buffer_selection);
assert!(config.multi_shot);
assert!(config.provided_buffers);
assert!(!config.sq_poll);
assert!(!config.defer_async_work);
}
#[test]
fn test_builder_pattern() {
let config = AdvancedConfig::new()
.with_buffer_selection(true)
.with_multi_shot(true)
.with_fast_poll(true);
assert!(config.buffer_selection);
assert!(config.multi_shot);
assert!(config.fast_poll);
assert!(!config.provided_buffers); }
#[test]
fn test_sq_poll_configuration() {
let config = AdvancedConfig::new().with_sq_poll(true, Some(2));
assert!(config.sq_poll);
assert_eq!(config.sq_thread_cpu, Some(2));
let config = AdvancedConfig::new().with_sq_poll(false, Some(2));
assert!(!config.sq_poll);
assert_eq!(config.sq_thread_cpu, None); }
#[test]
fn test_enabled_features() {
let config = AdvancedConfig::stable();
let features = config.enabled_features();
assert!(features.contains(&"buffer_selection"));
assert!(features.contains(&"fast_poll"));
assert!(!features.is_empty());
let default_config = AdvancedConfig::default();
assert!(default_config.enabled_features().is_empty());
}
#[test]
fn test_feature_count() {
let default_config = AdvancedConfig::default();
assert_eq!(default_config.feature_count(), 0);
let stable_config = AdvancedConfig::stable();
assert!(stable_config.feature_count() > 0);
let performance_config = AdvancedConfig::performance();
assert!(performance_config.feature_count() >= stable_config.feature_count());
}
#[test]
fn test_validation() {
let good_config = AdvancedConfig::stable();
let warnings = good_config.validate();
assert!(warnings.len() <= 1);
let problematic_config = AdvancedConfig::new()
.with_sq_poll(true, None)
.with_defer_taskrun(true);
let warnings = problematic_config.validate();
assert!(!warnings.is_empty());
}
#[test]
fn test_resource_intensive_validation() {
let intensive_config = AdvancedConfig {
sq_poll: true,
defer_async_work: true,
user_allocated_ring_memory: true,
sq_thread_cpu: Some(0),
advanced_task_work: true, ..AdvancedConfig::default()
};
let warnings = intensive_config.validate();
assert!(warnings.iter().any(|w| w.contains("resource-intensive")));
}
}