feat: Make packet processing continuous by default and add interval config

This commit is contained in:
Marco Cadetg (aider)
2025-05-10 12:27:35 +02:00
parent d236126e81
commit b2f4333b40
4 changed files with 38 additions and 37 deletions

View File

@@ -137,6 +137,8 @@ impl App {
let connections_update_clone = Arc::clone(&connections_update);
self.connections_data_shared = Some(connections_update_clone.clone()); // Store Arc for on_tick
let app_config = self.config.clone(); // Clone config to move into the thread
thread::spawn(move || -> Result<()> {
loop {
let mut monitor = monitor_clone.lock().unwrap();
@@ -159,10 +161,16 @@ impl App {
let mut connections = connections_update_clone.lock().unwrap();
*connections = new_connections;
// Sleep to avoid high CPU usage
// Sleep to avoid high CPU usage, controlled by config
drop(connections);
drop(monitor);
thread::sleep(std::time::Duration::from_millis(250)); // Update data more frequently
let sleep_duration_ms = if app_config.packet_processing_interval_ms == 0 {
1 // Minimal sleep (1ms) to prevent 100% CPU usage on one core
} else {
app_config.packet_processing_interval_ms
};
thread::sleep(std::time::Duration::from_millis(sleep_duration_ms));
}
});

View File

@@ -17,6 +17,8 @@ pub struct Config {
pub show_locations: bool,
/// Filter out localhost (loopback) traffic
pub filter_localhost: bool,
/// Interval in milliseconds for the packet processing loop's sleep. 0 means minimal sleep for continuous processing.
pub packet_processing_interval_ms: u64,
/// Custom configuration file path
pub config_path: Option<PathBuf>,
}
@@ -30,6 +32,7 @@ impl Default for Config {
refresh_interval: 1000,
show_locations: true,
filter_localhost: true,
packet_processing_interval_ms: 0, // Default to continuous processing (minimal sleep)
config_path: None,
}
}
@@ -92,6 +95,11 @@ impl Config {
config.filter_localhost = false;
}
}
"packet_processing_interval_ms" => {
if let Ok(interval) = value.parse::<u64>() {
config.packet_processing_interval_ms = interval;
}
}
_ => {
// Ignore unknown keys
}

View File

@@ -49,6 +49,15 @@ fn main() -> Result<()> {
.help("Interface language (en, fr, etc.)")
.required(false),
)
.arg(
Arg::new("packet_processing_interval")
.short('P')
.long("packet-processing-interval")
.value_name("MILLISECONDS")
.help("Interval for packet processing loop sleep (ms). 0 for continuous.")
.value_parser(clap::value_parser!(u64))
.required(false),
)
.get_matches();
// Initialize configuration
@@ -68,6 +77,11 @@ fn main() -> Result<()> {
info!("Using language: {}", language);
}
if let Some(interval) = matches.get_one::<u64>("packet_processing_interval") {
config.packet_processing_interval_ms = *interval;
info!("Using packet processing interval: {}ms", interval);
}
// Initialize internationalization
let i18n = i18n::I18n::new(&config.language)?;
info!(

View File

@@ -168,8 +168,8 @@ pub struct NetworkMonitor {
collect_process_info: bool,
filter_localhost: bool,
local_ips: std::collections::HashSet<IpAddr>,
last_packet_check: Instant,
initial_packet_processing_done: bool, // New flag
// last_packet_check: Instant, // Removed for continuous processing by default
// initial_packet_processing_done: bool, // Removed
}
/// Manages lookup of service names from a services file.
@@ -394,10 +394,7 @@ impl NetworkMonitor {
// geo_db, // Field removed
collect_process_info: false,
filter_localhost,
// Initialize last_packet_check to a time in the past
// to ensure the first call to process_packets runs.
last_packet_check: Instant::now() - Duration::from_millis(200),
initial_packet_processing_done: false, // Initialize the new flag
// last_packet_check and initial_packet_processing_done removed
})
}
@@ -659,35 +656,9 @@ impl NetworkMonitor {
} // This closes the `match protocol`
}; // This closes the `process_single_packet` closure definition
// If it's the very first run (during App::start_capture), be extremely lightweight.
if !self.initial_packet_processing_done {
log::debug!("NetworkMonitor::process_packets - First run, skipping detailed packet processing for quick startup.");
// Optionally, process a single packet or none at all.
// For now, let's try processing 0-1 packets to see if it helps.
if let Some(ref mut cap) = self.capture {
match cap.next_packet() {
Ok(packet) => {
process_single_packet(packet.data, &mut self.connections, &self.local_ips, &self.interface, &self.service_lookup);
log::debug!("NetworkMonitor::process_packets - Processed one packet on first run.");
}
Err(pcap::Error::TimeoutExpired) => {
log::debug!("NetworkMonitor::process_packets - No packets on first check.");
}
Err(e) => {
error!("NetworkMonitor::process_packets - Error reading packet on first run: {}", e);
}
}
}
self.initial_packet_processing_done = true;
self.last_packet_check = Instant::now(); // Update timestamp
return Ok(());
}
// Only check packets every 100ms to avoid too frequent checks for subsequent runs
if self.last_packet_check.elapsed() < Duration::from_millis(100) {
return Ok(());
}
self.last_packet_check = Instant::now();
// Removed initial_packet_processing_done logic and last_packet_check cooldown.
// The loop will now attempt to process packets more continuously,
// controlled by the sleep interval in the app.rs background thread.
// Get packets from the capture
if let Some(ref mut cap) = self.capture {