Skip to main content

Mountain/IPC/Common/PerformanceMetrics/
PerformanceMetrics.rs

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