use std::sync::{
Arc,
atomic::{AtomicU64, Ordering},
};
#[derive(Debug, Default)]
pub struct ConnectionMetrics {
pending_send_bytes: AtomicU64,
sent_unacked_bytes: AtomicU64,
sent_acked_bytes: AtomicU64,
}
impl ConnectionMetrics {
pub fn new() -> Self {
Self::default()
}
pub fn add_pending_send(&self, bytes: u64) {
self.pending_send_bytes.fetch_add(bytes, Ordering::Relaxed);
}
pub fn on_data_sent(&self, bytes: u64) {
self.sent_unacked_bytes.fetch_add(bytes, Ordering::Relaxed);
self.pending_send_bytes.fetch_sub(bytes, Ordering::Relaxed);
}
pub fn on_data_acked(&self, bytes: u64) {
self.sent_acked_bytes.fetch_add(bytes, Ordering::Relaxed);
self.sent_unacked_bytes.fetch_sub(bytes, Ordering::Relaxed);
}
pub fn pending_send_bytes(&self) -> u64 {
self.pending_send_bytes.load(Ordering::Relaxed)
}
pub fn sent_unacked_bytes(&self) -> u64 {
self.sent_unacked_bytes.load(Ordering::Relaxed)
}
pub fn sent_acked_bytes(&self) -> u64 {
self.sent_acked_bytes.load(Ordering::Relaxed)
}
}
pub type ArcConnectionMetrics = Arc<ConnectionMetrics>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_connection_metrics_new() {
let metrics = ConnectionMetrics::new();
assert_eq!(metrics.pending_send_bytes(), 0);
assert_eq!(metrics.sent_unacked_bytes(), 0);
assert_eq!(metrics.sent_acked_bytes(), 0);
}
#[test]
fn test_add_pending_send() {
let metrics = ConnectionMetrics::new();
metrics.add_pending_send(100);
assert_eq!(metrics.pending_send_bytes(), 100);
metrics.add_pending_send(50);
assert_eq!(metrics.pending_send_bytes(), 150);
}
#[test]
fn test_on_data_sent() {
let metrics = ConnectionMetrics::new();
metrics.add_pending_send(200);
metrics.on_data_sent(150);
assert_eq!(metrics.pending_send_bytes(), 50);
assert_eq!(metrics.sent_unacked_bytes(), 150);
}
#[test]
fn test_on_data_acked() {
let metrics = ConnectionMetrics::new();
metrics.add_pending_send(200);
metrics.on_data_sent(150);
metrics.on_data_acked(100);
assert_eq!(metrics.pending_send_bytes(), 50);
assert_eq!(metrics.sent_unacked_bytes(), 50);
assert_eq!(metrics.sent_acked_bytes(), 100);
}
#[test]
fn test_full_data_flow() {
let metrics = ConnectionMetrics::new();
metrics.add_pending_send(1000);
assert_eq!(metrics.pending_send_bytes(), 1000);
assert_eq!(metrics.sent_unacked_bytes(), 0);
assert_eq!(metrics.sent_acked_bytes(), 0);
metrics.on_data_sent(600);
assert_eq!(metrics.pending_send_bytes(), 400);
assert_eq!(metrics.sent_unacked_bytes(), 600);
assert_eq!(metrics.sent_acked_bytes(), 0);
metrics.on_data_acked(300);
assert_eq!(metrics.pending_send_bytes(), 400);
assert_eq!(metrics.sent_unacked_bytes(), 300);
assert_eq!(metrics.sent_acked_bytes(), 300);
metrics.on_data_sent(400);
assert_eq!(metrics.pending_send_bytes(), 0);
assert_eq!(metrics.sent_unacked_bytes(), 700);
assert_eq!(metrics.sent_acked_bytes(), 300);
metrics.on_data_acked(700);
assert_eq!(metrics.pending_send_bytes(), 0);
assert_eq!(metrics.sent_unacked_bytes(), 0);
assert_eq!(metrics.sent_acked_bytes(), 1000);
}
#[test]
fn test_arc_connection_metrics() {
let metrics = Arc::new(ConnectionMetrics::new());
let metrics_clone = Arc::clone(&metrics);
metrics.add_pending_send(100);
assert_eq!(metrics_clone.pending_send_bytes(), 100);
metrics_clone.on_data_sent(100);
assert_eq!(metrics.sent_unacked_bytes(), 100);
assert_eq!(metrics.pending_send_bytes(), 0);
}
}