flare_core/client/connection/
state.rs1use std::sync::{Arc, Mutex};
6
7use crate::common::platform::{MonotonicInstant, monotonic_now};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum ConnectionState {
12 Disconnected,
14 Connecting,
16 Connected,
18 Disconnecting,
20 Failed,
22 Reconnecting,
24}
25
26impl ConnectionState {
27 pub fn can_send(&self) -> bool {
29 matches!(self, ConnectionState::Connected)
30 }
31
32 pub fn can_connect(&self) -> bool {
34 matches!(
35 self,
36 ConnectionState::Disconnected | ConnectionState::Failed
37 )
38 }
39
40 pub fn is_connecting(&self) -> bool {
42 matches!(
43 self,
44 ConnectionState::Connecting | ConnectionState::Reconnecting
45 )
46 }
47}
48
49pub struct ConnectionStateManager {
51 state: Arc<Mutex<ConnectionState>>,
52 state_changed_at: Arc<Mutex<MonotonicInstant>>,
53 connect_started_at: Arc<Mutex<Option<MonotonicInstant>>>,
54}
55
56impl Clone for ConnectionStateManager {
57 fn clone(&self) -> Self {
58 Self {
59 state: Arc::clone(&self.state),
60 state_changed_at: Arc::clone(&self.state_changed_at),
61 connect_started_at: Arc::clone(&self.connect_started_at),
62 }
63 }
64}
65
66impl ConnectionStateManager {
67 pub fn new() -> Self {
68 Self {
69 state: Arc::new(Mutex::new(ConnectionState::Disconnected)),
70 state_changed_at: Arc::new(Mutex::new(monotonic_now())),
71 connect_started_at: Arc::new(Mutex::new(None)),
72 }
73 }
74
75 pub fn set_state(&self, new_state: ConnectionState) {
76 if let Ok(mut state) = self.state.lock() {
77 *state = new_state;
78 }
79 if let Ok(mut changed_at) = self.state_changed_at.lock() {
80 *changed_at = monotonic_now();
81 }
82 }
83
84 pub fn get_state(&self) -> ConnectionState {
85 self.state
86 .lock()
87 .map(|s| *s)
88 .unwrap_or(ConnectionState::Disconnected)
89 }
90
91 pub fn start_connecting(&self) {
92 self.set_state(ConnectionState::Connecting);
93 if let Ok(mut started_at) = self.connect_started_at.lock() {
94 *started_at = Some(monotonic_now());
95 }
96 }
97
98 pub fn set_connected(&self) {
99 self.set_state(ConnectionState::Connected);
100 if let Ok(mut started_at) = self.connect_started_at.lock() {
101 *started_at = None;
102 }
103 }
104
105 pub fn set_disconnected(&self) {
106 self.set_state(ConnectionState::Disconnected);
107 if let Ok(mut started_at) = self.connect_started_at.lock() {
108 *started_at = None;
109 }
110 }
111
112 pub fn set_failed(&self) {
113 self.set_state(ConnectionState::Failed);
114 if let Ok(mut started_at) = self.connect_started_at.lock() {
115 *started_at = None;
116 }
117 }
118
119 pub fn set_reconnecting(&self) {
120 self.set_state(ConnectionState::Reconnecting);
121 if let Ok(mut started_at) = self.connect_started_at.lock() {
122 *started_at = Some(monotonic_now());
123 }
124 }
125
126 pub fn state_changed_at(&self) -> MonotonicInstant {
127 self.state_changed_at
128 .lock()
129 .map(|t| *t)
130 .unwrap_or_else(|_| monotonic_now())
131 }
132
133 pub fn connect_duration(&self) -> Option<std::time::Duration> {
134 self.connect_started_at
135 .lock()
136 .ok()
137 .and_then(|started_at| started_at.map(|start| start.elapsed()))
138 }
139}
140
141impl Default for ConnectionStateManager {
142 fn default() -> Self {
143 Self::new()
144 }
145}