use std::time::Duration;
use serde::{Deserialize, Serialize};
use crate::app::worker::WorkerConfig;
use crate::constants::workers;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CoordinatorConfig {
pub worker_count: usize,
pub progress_update_interval: Duration,
pub shutdown_timeout: Duration,
pub enable_progress_bar: bool,
pub verbose_logging: bool,
pub progress_batch_size: usize,
pub worker_config: WorkerConfig,
}
impl Default for CoordinatorConfig {
fn default() -> Self {
Self {
worker_count: workers::DEFAULT_WORKER_COUNT,
progress_update_interval: Duration::from_millis(500),
shutdown_timeout: Duration::from_secs(30),
enable_progress_bar: true,
verbose_logging: false,
progress_batch_size: 10000,
worker_config: WorkerConfig::default(),
}
}
}
impl CoordinatorConfig {
pub fn with_worker_count(mut self, count: usize) -> Self {
self.worker_count = count;
self.worker_config.worker_count = count;
self
}
pub fn with_verbose_logging(mut self, enabled: bool) -> Self {
self.verbose_logging = enabled;
self
}
pub fn with_progress_interval(mut self, interval: Duration) -> Self {
self.progress_update_interval = interval;
self
}
pub fn with_shutdown_timeout(mut self, timeout: Duration) -> Self {
self.shutdown_timeout = timeout;
self
}
pub fn validate(&self) -> Result<(), String> {
if self.progress_update_interval.is_zero() {
return Err("Progress update interval cannot be zero".to_string());
}
if self.shutdown_timeout.is_zero() {
return Err("Shutdown timeout cannot be zero".to_string());
}
if self.progress_batch_size == 0 {
return Err("Progress batch size cannot be zero".to_string());
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config_is_valid() {
let config = CoordinatorConfig::default();
assert!(config.validate().is_ok());
assert_eq!(config.worker_count, workers::DEFAULT_WORKER_COUNT);
assert!(config.enable_progress_bar);
assert!(!config.verbose_logging);
}
#[test]
fn test_config_builder_methods() {
let config = CoordinatorConfig::default()
.with_worker_count(16)
.with_verbose_logging(true)
.with_progress_interval(Duration::from_millis(100))
.with_shutdown_timeout(Duration::from_secs(60));
assert_eq!(config.worker_count, 16);
assert_eq!(config.worker_config.worker_count, 16);
assert!(config.verbose_logging);
assert_eq!(config.progress_update_interval, Duration::from_millis(100));
assert_eq!(config.shutdown_timeout, Duration::from_secs(60));
assert!(config.validate().is_ok());
}
#[test]
fn test_config_validation() {
let mut config = CoordinatorConfig {
progress_update_interval: Duration::ZERO,
..Default::default()
};
assert!(config.validate().is_err());
config = CoordinatorConfig::default();
config.shutdown_timeout = Duration::ZERO;
assert!(config.validate().is_err());
config = CoordinatorConfig::default();
config.progress_batch_size = 0;
assert!(config.validate().is_err());
}
}