fix(rustproxy): prune stale per-route metrics, add per-route rate limiter caching and regex cache, and improve connection tracking cleanup to prevent memory growth
This commit is contained in:
@@ -95,10 +95,11 @@ impl ConnectionTracker {
|
||||
pub fn connection_closed(&self, ip: &IpAddr) {
|
||||
if let Some(counter) = self.active.get(ip) {
|
||||
let prev = counter.value().fetch_sub(1, Ordering::Relaxed);
|
||||
// Clean up zero entries
|
||||
// Clean up zero entries to prevent memory growth
|
||||
if prev <= 1 {
|
||||
drop(counter);
|
||||
self.active.remove(ip);
|
||||
self.timestamps.remove(ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -205,10 +206,13 @@ impl ConnectionTracker {
|
||||
let zombies = tracker.scan_zombies();
|
||||
if !zombies.is_empty() {
|
||||
warn!(
|
||||
"Detected {} zombie connection(s): {:?}",
|
||||
"Cleaning up {} zombie connection(s): {:?}",
|
||||
zombies.len(),
|
||||
zombies
|
||||
);
|
||||
for id in &zombies {
|
||||
tracker.unregister_connection(*id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -304,6 +308,30 @@ mod tests {
|
||||
assert_eq!(tracker.tracked_ips(), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_timestamps_cleaned_on_last_close() {
|
||||
let tracker = ConnectionTracker::new(None, Some(100));
|
||||
let ip: IpAddr = "10.0.0.1".parse().unwrap();
|
||||
|
||||
// try_accept populates the timestamps map (when rate limiting is enabled)
|
||||
assert!(tracker.try_accept(&ip));
|
||||
tracker.connection_opened(&ip);
|
||||
assert!(tracker.try_accept(&ip));
|
||||
tracker.connection_opened(&ip);
|
||||
|
||||
// Timestamps should exist
|
||||
assert!(tracker.timestamps.get(&ip).is_some());
|
||||
|
||||
// Close one connection — timestamps should still exist
|
||||
tracker.connection_closed(&ip);
|
||||
assert!(tracker.timestamps.get(&ip).is_some());
|
||||
|
||||
// Close last connection — timestamps should be cleaned up
|
||||
tracker.connection_closed(&ip);
|
||||
assert!(tracker.timestamps.get(&ip).is_none());
|
||||
assert!(tracker.active.get(&ip).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_register_unregister_connection() {
|
||||
let tracker = ConnectionTracker::new(None, None);
|
||||
|
||||
Reference in New Issue
Block a user