Mountain/IPC/Common/ServiceInfo/
ServiceInfo.rs1#![allow(non_snake_case)]
2
3use 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}