use super::{PowerMode, ReconfigResult};
use crate::types::ResourceCategory;
pub struct AutoReconfigurator {
current_config: NodeConfig,
templates: ConfigTemplates,
history: Vec<ReconfigEvent>,
}
impl AutoReconfigurator {
pub fn new() -> Self {
Self {
current_config: NodeConfig::balanced(),
templates: ConfigTemplates::new(),
history: Vec::new(),
}
}
pub fn reconfigure(&mut self, resources: ResourceCategory) -> ReconfigResult {
let new_config = match resources {
ResourceCategory::Abundant => self.templates.full_power(),
ResourceCategory::Normal => self.templates.balanced(),
ResourceCategory::Limited => self.templates.low_power(),
ResourceCategory::Critical => self.templates.minimal(),
};
if new_config != self.current_config {
let event = ReconfigEvent {
timestamp: std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_millis() as u64,
from: self.current_config.mode,
to: new_config.mode,
reason: format!("Resource category: {:?}", resources),
};
self.history.push(event);
self.current_config = new_config.clone();
ReconfigResult::Changed(new_config)
} else {
ReconfigResult::NoChange
}
}
pub fn current(&self) -> &NodeConfig {
&self.current_config
}
pub fn history(&self) -> &[ReconfigEvent] {
&self.history
}
}
impl Default for AutoReconfigurator {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct NodeConfig {
pub mode: PowerMode,
pub memory_limit: usize,
pub validation_parallelism: usize,
pub gossip_multiplier: f32,
pub ai_enabled: bool,
pub compression_enabled: bool,
}
impl NodeConfig {
pub fn full_power() -> Self {
Self {
mode: PowerMode::Full,
memory_limit: 1024 * 1024 * 1024, validation_parallelism: 16,
gossip_multiplier: 2.0,
ai_enabled: true,
compression_enabled: false,
}
}
pub fn balanced() -> Self {
Self {
mode: PowerMode::Balanced,
memory_limit: 256 * 1024 * 1024, validation_parallelism: 4,
gossip_multiplier: 1.0,
ai_enabled: true,
compression_enabled: false,
}
}
pub fn low_power() -> Self {
Self {
mode: PowerMode::Low,
memory_limit: 64 * 1024 * 1024, validation_parallelism: 2,
gossip_multiplier: 0.5,
ai_enabled: true,
compression_enabled: true,
}
}
pub fn minimal() -> Self {
Self {
mode: PowerMode::Critical,
memory_limit: 16 * 1024 * 1024, validation_parallelism: 1,
gossip_multiplier: 0.25,
ai_enabled: false,
compression_enabled: true,
}
}
}
struct ConfigTemplates;
impl ConfigTemplates {
fn new() -> Self {
Self
}
fn full_power(&self) -> NodeConfig {
NodeConfig::full_power()
}
fn balanced(&self) -> NodeConfig {
NodeConfig::balanced()
}
fn low_power(&self) -> NodeConfig {
NodeConfig::low_power()
}
fn minimal(&self) -> NodeConfig {
NodeConfig::minimal()
}
}
#[derive(Debug, Clone)]
pub struct ReconfigEvent {
pub timestamp: u64,
pub from: PowerMode,
pub to: PowerMode,
pub reason: String,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_auto_reconfigurator() {
let mut reconf = AutoReconfigurator::new();
assert_eq!(reconf.current().mode, PowerMode::Balanced);
let result = reconf.reconfigure(ResourceCategory::Limited);
assert!(matches!(result, ReconfigResult::Changed(_)));
assert_eq!(reconf.current().mode, PowerMode::Low);
let result = reconf.reconfigure(ResourceCategory::Limited);
assert!(matches!(result, ReconfigResult::NoChange));
}
#[test]
fn test_config_templates() {
let full = NodeConfig::full_power();
let minimal = NodeConfig::minimal();
assert!(full.memory_limit > minimal.memory_limit);
assert!(full.validation_parallelism > minimal.validation_parallelism);
assert!(full.ai_enabled);
assert!(!minimal.ai_enabled);
}
}