Mountain/IPC/Common/
ConnectionStatus.rs

1//! # Connection Status Tracking
2//!
3//! Provides types for tracking IPC connection health and state.
4//! Used across all IPC components to monitor connection status.
5
6use std::time::{Duration, Instant};
7
8use serde::{Deserialize, Serialize};
9
10/// Represents the current state of an IPC connection
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
12pub enum ConnectionState {
13	/// Connection is active and healthy
14	Connected,
15	/// Connection is being established
16	Connecting,
17	/// Connection is temporarily unavailable
18	Disconnected,
19	/// Connection has failed and needs recovery
20	Failed,
21	/// Connection is being closed gracefully
22	Closing,
23	/// Connection is closed and will not reopen
24	Closed,
25}
26
27/// Comprehensive connection status tracking
28#[derive(Debug, Clone, Serialize)]
29pub struct ConnectionStatus {
30	/// Current connection state
31	pub state:ConnectionState,
32	/// When the connection entered its current state (skipped for serialization
33	/// as Instant is not serializable)
34	#[serde(skip)]
35	pub state_since:Instant,
36	/// Count of connection attempts
37	pub connection_attempts:u32,
38	/// Timestamp of last successful connection (skipped for serialization as
39	/// Instant is not serializable)
40	#[serde(skip)]
41	pub last_connected:Option<Instant>,
42	/// Timestamp of last disconnection (skipped for serialization as Instant is
43	/// not serializable)
44	#[serde(skip)]
45	pub last_disconnected:Option<Instant>,
46	/// Total uptime duration
47	pub total_uptime:Duration,
48	/// Reason for last disconnection (if any)
49	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	/// Create a new connection status
68	pub fn new() -> Self { Self::default() }
69
70	/// Update connection state
71	pub fn update_state(&mut self, new_state:ConnectionState, error:Option<String>) {
72		if new_state != self.state {
73			// Track downtime if disconnecting
74			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			// Update timestamps
81			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	/// Check if connection is currently active
99	pub fn is_connected(&self) -> bool { self.state == ConnectionState::Connected }
100
101	/// Check if connection is in a healthy state
102	pub fn is_healthy(&self) -> bool { matches!(self.state, ConnectionState::Connected | ConnectionState::Connecting) }
103
104	/// Get the duration the connection has been in its current state
105	pub fn current_state_duration(&self) -> Duration { self.state_since.elapsed() }
106
107	/// Get the duration since last successful connection
108	pub fn time_since_last_connection(&self) -> Option<Duration> { self.last_connected.map(|t| t.elapsed()) }
109}
110