Skip to main content

Mountain/IPC/Common/ServiceInfo/
ServiceInfo.rs

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