Skip to main content

Mountain/IPC/Common/PerformanceMetrics/
PerformanceMetrics.rs

1
2//! Aggregate IPC perf snapshot: throughput, latency (avg + peak),
3//! compression ratio, pool utilisation, memory + CPU usage, and
4//! success/failure counters. `RecordMessage` updates the running mean
5//! latency without bias under high message volume.
6
7use std::time::{Duration, Instant};
8
9use serde::Serialize;
10
11#[derive(Debug, Clone, Serialize)]
12pub struct Struct {
13	pub MessagesPerSecond:f64,
14
15	pub AverageLatencyMs:f64,
16
17	pub PeakLatencyMs:f64,
18
19	pub CompressionRatio:f64,
20
21	pub PoolUtilization:f64,
22
23	pub MemoryUsageBytes:u64,
24
25	pub CpuUsagePercent:f64,
26
27	pub TotalMessages:u64,
28
29	pub FailedMessages:u64,
30
31	#[serde(skip)]
32	pub LastUpdated:Instant,
33}
34
35impl Struct {
36	pub fn new() -> Self {
37		Self {
38			MessagesPerSecond:0.0,
39
40			AverageLatencyMs:0.0,
41
42			PeakLatencyMs:0.0,
43
44			CompressionRatio:1.0,
45
46			PoolUtilization:0.0,
47
48			MemoryUsageBytes:0,
49
50			CpuUsagePercent:0.0,
51
52			TotalMessages:0,
53
54			FailedMessages:0,
55
56			LastUpdated:Instant::now(),
57		}
58	}
59
60	pub fn RecordMessage(&mut self, Latency:Duration) {
61		let LatencyMs = Latency.as_millis() as f64;
62
63		if self.TotalMessages > 0 {
64			self.AverageLatencyMs =
65				(self.AverageLatencyMs * self.TotalMessages as f64 + LatencyMs) / (self.TotalMessages + 1) as f64;
66		} else {
67			self.AverageLatencyMs = LatencyMs;
68		}
69
70		if LatencyMs > self.PeakLatencyMs {
71			self.PeakLatencyMs = LatencyMs;
72		}
73
74		self.TotalMessages += 1;
75
76		self.LastUpdated = Instant::now();
77	}
78
79	pub fn RecordFailure(&mut self) {
80		self.FailedMessages += 1;
81
82		self.LastUpdated = Instant::now();
83	}
84
85	pub fn SuccessRate(&self) -> f64 {
86		if self.TotalMessages == 0 {
87			return 1.0;
88		}
89
90		1.0 - (self.FailedMessages as f64 / self.TotalMessages as f64)
91	}
92
93	pub fn IsLatencyAcceptable(&self, ThresholdMs:f64) -> bool {
94		self.AverageLatencyMs <= ThresholdMs && self.PeakLatencyMs <= ThresholdMs * 2.0
95	}
96
97	pub fn SuccessRatePercent(&self) -> f64 { self.SuccessRate() * 100.0 }
98}
99
100impl Default for Struct {
101	fn default() -> Self { Self::new() }
102}