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 pub Version:String,
18 pub State:ServiceState::Enum,
19 #[serde(skip)]
20 pub StateSince:Instant,
21 pub Uptime:Duration,
22 #[serde(skip)]
23 pub LastHeartbeat:Option<Instant>,
24 pub Dependencies:Vec<String>,
25 pub Performance:ServicePerformance::Struct,
26 pub Endpoint:Option<ServiceEndpoint::Struct>,
27}
28
29impl Struct {
30 pub fn new(Name:impl Into<String>, Version:impl Into<String>) -> Self {
31 Self {
32 Name:Name.into(),
33 Version:Version.into(),
34 State:ServiceState::Enum::Starting,
35 StateSince:Instant::now(),
36 Uptime:Duration::ZERO,
37 LastHeartbeat:None,
38 Dependencies:Vec::new(),
39 Performance:ServicePerformance::Struct::new(),
40 Endpoint:None,
41 }
42 }
43
44 pub fn UpdateState(&mut self, NewState:ServiceState::Enum) {
45 self.State = NewState;
46 self.StateSince = Instant::now();
47 }
48
49 pub fn RecordHeartbeat(&mut self) {
50 self.LastHeartbeat = Some(Instant::now());
51 if self.State == ServiceState::Enum::Running {
52 self.Uptime = self.StateSince.elapsed();
53 }
54 }
55
56 pub fn IsHealthy(&self) -> bool {
57 if !self.State.IsOperational() {
58 return false;
59 }
60 if let Some(Heartbeat) = self.LastHeartbeat
61 && Heartbeat.elapsed() > Duration::from_secs(30)
62 {
63 return false;
64 }
65 if self.Performance.ErrorRate() > 0.1 {
66 return false;
67 }
68 true
69 }
70
71 pub fn AddDependency(&mut self, Dependency:impl Into<String>) { self.Dependencies.push(Dependency.into()); }
72}