Mountain/IPC/Common/
ConnectionStatus.rs1use std::time::{Duration, Instant};
7
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
12pub enum ConnectionState {
13 Connected,
15 Connecting,
17 Disconnected,
19 Failed,
21 Closing,
23 Closed,
25}
26
27#[derive(Debug, Clone, Serialize)]
29pub struct ConnectionStatus {
30 pub state:ConnectionState,
32 #[serde(skip)]
35 pub state_since:Instant,
36 pub connection_attempts:u32,
38 #[serde(skip)]
41 pub last_connected:Option<Instant>,
42 #[serde(skip)]
45 pub last_disconnected:Option<Instant>,
46 pub total_uptime:Duration,
48 pub last_error:Option<String>,
50}
51
52impl Default for ConnectionStatus {
53 fn default() -> Self {
54 Self {
55 state:ConnectionState::Disconnected,
56 state_since:Instant::now(),
57 connection_attempts:0,
58 last_connected:None,
59 last_disconnected:None,
60 total_uptime:Duration::ZERO,
61 last_error:None,
62 }
63 }
64}
65
66impl ConnectionStatus {
67 pub fn new() -> Self { Self::default() }
69
70 pub fn update_state(&mut self, new_state:ConnectionState, error:Option<String>) {
72 if new_state != self.state {
73 if self.state == ConnectionState::Connected {
75 if let Some(connected_since) = self.last_connected {
76 self.total_uptime += connected_since.elapsed();
77 }
78 }
79
80 match new_state {
82 ConnectionState::Connected => {
83 self.last_connected = Some(Instant::now());
84 self.connection_attempts += 1;
85 },
86 ConnectionState::Disconnected | ConnectionState::Failed => {
87 self.last_disconnected = Some(Instant::now());
88 },
89 _ => {},
90 }
91
92 self.state = new_state;
93 self.state_since = Instant::now();
94 self.last_error = error;
95 }
96 }
97
98 pub fn is_connected(&self) -> bool { self.state == ConnectionState::Connected }
100
101 pub fn is_healthy(&self) -> bool { matches!(self.state, ConnectionState::Connected | ConnectionState::Connecting) }
103
104 pub fn current_state_duration(&self) -> Duration { self.state_since.elapsed() }
106
107 pub fn time_since_last_connection(&self) -> Option<Duration> { self.last_connected.map(|t| t.elapsed()) }
109}
110