Mountain/IPC/Common/ServiceInfo/
ServiceInfo.rs1
2use 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}