Skip to main content

Mountain/IPC/Common/ServiceInfo/
ServiceInfo.rs

1
2//! Per-service descriptor: name, version, lifecycle state, performance
3//! counters, dependency list, optional endpoint. Health is the
4//! conjunction of operational state, recent heartbeat (≤ 30s), and
5//! error rate ≤ 10 %.
6
7use std::time::{Duration, Instant};
8
9use serde::Serialize;
10
11use crate::IPC::Common::ServiceInfo::{ServiceEndpoint, ServicePerformance, ServiceState};
12
13#[derive(Debug, Clone, Serialize)]
14pub struct Struct {
15	pub Name:String,
16
17	pub Version:String,
18
19	pub State:ServiceState::Enum,
20
21	#[serde(skip)]
22	pub StateSince:Instant,
23
24	pub Uptime:Duration,
25
26	#[serde(skip)]
27	pub LastHeartbeat:Option<Instant>,
28
29	pub Dependencies:Vec<String>,
30
31	pub Performance:ServicePerformance::Struct,
32
33	pub Endpoint:Option<ServiceEndpoint::Struct>,
34}
35
36impl Struct {
37	pub fn new(Name:impl Into<String>, Version:impl Into<String>) -> Self {
38		Self {
39			Name:Name.into(),
40
41			Version:Version.into(),
42
43			State:ServiceState::Enum::Starting,
44
45			StateSince:Instant::now(),
46
47			Uptime:Duration::ZERO,
48
49			LastHeartbeat:None,
50
51			Dependencies:Vec::new(),
52
53			Performance:ServicePerformance::Struct::new(),
54
55			Endpoint:None,
56		}
57	}
58
59	pub fn UpdateState(&mut self, NewState:ServiceState::Enum) {
60		self.State = NewState;
61
62		self.StateSince = Instant::now();
63	}
64
65	pub fn RecordHeartbeat(&mut self) {
66		self.LastHeartbeat = Some(Instant::now());
67
68		if self.State == ServiceState::Enum::Running {
69			self.Uptime = self.StateSince.elapsed();
70		}
71	}
72
73	pub fn IsHealthy(&self) -> bool {
74		if !self.State.IsOperational() {
75			return false;
76		}
77
78		if let Some(Heartbeat) = self.LastHeartbeat
79			&& Heartbeat.elapsed() > Duration::from_secs(30)
80		{
81			return false;
82		}
83
84		if self.Performance.ErrorRate() > 0.1 {
85			return false;
86		}
87
88		true
89	}
90
91	pub fn AddDependency(&mut self, Dependency:impl Into<String>) { self.Dependencies.push(Dependency.into()); }
92}