use knust::{Component, ConnectionType, Knx, LogLevel, LoggingConfig};
use std::time::Duration;
use tokio::time::sleep;
#[allow(clippy::too_many_lines)]
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
println!("๐ Knx Memory Optimization Demo");
println!("==================================");
let mut logging_config = LoggingConfig::new();
logging_config.set_component_level(Component::Application, LogLevel::Info);
logging_config.set_component_level(Component::Transport, LogLevel::Debug);
logging_config.set_component_level(Component::Protocol, LogLevel::Debug);
logging_config.set_protocol_events(true);
let knx = Knx::builder()
.connection_type(ConnectionType::Routing)
.memory_limit_mb(32) .max_connections(5) .build()
.await?;
println!("โ
Knx instance created with memory management");
let initial_stats = knx.memory_stats().await;
println!("\n๐ Initial Memory Statistics:");
println!(" Current usage: {} bytes", initial_stats.current_usage);
println!(" Peak usage: {} bytes", initial_stats.peak_usage);
println!(" Memory limit: {}%", knx.memory_usage_percentage());
println!(" Within bounds: {}", knx.memory_within_bounds());
println!("\nโก Simulating operations for performance monitoring...");
match knx.connect().await {
Ok(()) => {
println!("โ
Connected to KNX network");
if let Err(e) = knx.start().await {
println!("โ ๏ธ Failed to start telegram processing: {e}");
}
sleep(Duration::from_secs(2)).await;
}
Err(e) => {
println!("โ ๏ธ Connection failed (expected without real gateway): {e}");
}
}
println!("\n๐งน Performing memory cleanup...");
let freed_bytes = knx.force_cleanup().await;
println!(" Freed {freed_bytes} bytes");
let updated_stats = knx.memory_stats().await;
println!("\n๐ Updated Memory Statistics:");
println!(" Current usage: {} bytes", updated_stats.current_usage);
println!(" Peak usage: {} bytes", updated_stats.peak_usage);
println!(" Memory limit: {}%", knx.memory_usage_percentage());
println!(" Within bounds: {}", knx.memory_within_bounds());
println!("\n๐ Memory Usage by Component:");
println!(
" Transport: {} bytes",
updated_stats.component_usage.transport
);
println!(
" Protocol: {} bytes",
updated_stats.component_usage.protocol
);
println!(" Device: {} bytes", updated_stats.component_usage.device);
println!(
" Application: {} bytes",
updated_stats.component_usage.application
);
println!(
" Security: {} bytes",
updated_stats.component_usage.security
);
let perf_stats = knx.performance_stats().await;
println!("\nโก Performance Statistics:");
if perf_stats.paths.is_empty() {
println!(" No performance data collected yet");
} else {
for (path, entry) in &perf_stats.paths {
println!(
" {}: {} calls, avg {:?}, min {:?}, max {:?}",
path, entry.call_count, entry.avg_duration, entry.min_duration, entry.max_duration
);
}
}
println!("\n๐งช Testing memory allocation limits...");
let memory_monitor = knx.memory_stats().await;
println!(
" Current memory usage: {} bytes",
memory_monitor.current_usage
);
if knx.memory_within_bounds() {
println!(" โ
Memory usage is within acceptable bounds");
} else {
println!(" โ ๏ธ Memory usage exceeds bounds!");
}
println!("\n๐ Shutting down Knx...");
knx.shutdown().await?;
let final_stats = knx.memory_stats().await;
println!("\n๐ Final Memory Statistics (after shutdown):");
println!(" Current usage: {} bytes", final_stats.current_usage);
println!(" Peak usage: {} bytes", final_stats.peak_usage);
println!(" Memory usage: {}%", knx.memory_usage_percentage());
println!("\nโ
Memory optimization demo completed successfully!");
println!("\n๐ก Key Features Demonstrated:");
println!(" โข Memory usage monitoring and limits");
println!(" โข Connection pool management");
println!(" โข Performance hot path tracking");
println!(" โข Automatic memory cleanup");
println!(" โข Component-specific resource tracking");
println!(" โข Graceful resource cleanup on shutdown");
Ok(())
}