Skip to main content

Mountain/IPC/Common/PerformanceMetrics/
PerformanceMetrics.rs

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