use std::time::Duration;
#[derive(Debug, Clone)]
pub struct BatchConfig {
pub max_batch_size: usize,
pub max_latency: Duration,
pub queue_capacity: Option<usize>,
pub response_timeout: Option<Duration>,
pub max_in_flight_per_feed: usize,
pub startup_timeout: Option<Duration>,
}
impl BatchConfig {
pub fn new(
max_batch_size: usize,
max_latency: Duration,
) -> Result<Self, nv_core::error::ConfigError> {
if max_batch_size == 0 {
return Err(nv_core::error::ConfigError::InvalidPolicy {
detail: "batch max_batch_size must be >= 1".into(),
});
}
if max_latency.is_zero() {
return Err(nv_core::error::ConfigError::InvalidPolicy {
detail: "batch max_latency must be > 0".into(),
});
}
Ok(Self {
max_batch_size,
max_latency,
queue_capacity: None,
response_timeout: None,
max_in_flight_per_feed: 1,
startup_timeout: None,
})
}
#[must_use]
pub fn with_queue_capacity(mut self, capacity: Option<usize>) -> Self {
self.queue_capacity = capacity;
self
}
#[must_use]
pub fn with_response_timeout(mut self, timeout: Option<Duration>) -> Self {
self.response_timeout = timeout;
self
}
#[must_use]
pub fn with_max_in_flight_per_feed(mut self, max: usize) -> Self {
self.max_in_flight_per_feed = max;
self
}
#[must_use]
pub fn with_startup_timeout(mut self, timeout: Option<Duration>) -> Self {
self.startup_timeout = timeout;
self
}
pub fn validate(&self) -> Result<(), nv_core::error::ConfigError> {
use nv_core::error::ConfigError;
if self.max_batch_size == 0 {
return Err(ConfigError::InvalidPolicy {
detail: "batch max_batch_size must be >= 1".into(),
});
}
if self.max_latency.is_zero() {
return Err(ConfigError::InvalidPolicy {
detail: "batch max_latency must be > 0".into(),
});
}
if let Some(rt) = self.response_timeout
&& rt.is_zero()
{
return Err(ConfigError::InvalidPolicy {
detail: "batch response_timeout must be > 0".into(),
});
}
if let Some(cap) = self.queue_capacity
&& cap < self.max_batch_size
{
return Err(ConfigError::InvalidPolicy {
detail: format!(
"batch queue_capacity ({cap}) must be >= max_batch_size ({})",
self.max_batch_size
),
});
}
if self.max_in_flight_per_feed == 0 {
return Err(ConfigError::InvalidPolicy {
detail: "batch max_in_flight_per_feed must be >= 1".into(),
});
}
if let Some(st) = self.startup_timeout
&& st.is_zero()
{
return Err(ConfigError::InvalidPolicy {
detail: "batch startup_timeout must be > 0".into(),
});
}
Ok(())
}
}
impl Default for BatchConfig {
fn default() -> Self {
Self {
max_batch_size: 4,
max_latency: Duration::from_millis(50),
queue_capacity: None,
response_timeout: None,
max_in_flight_per_feed: 1,
startup_timeout: None,
}
}
}