Skip to main content

DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/IPC/Common/ServiceInfo/
ServiceInfo.rs

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