confitdb/
server_control.rs

1use crate::server_error::ServerError;
2use crate::server_status::ServerStatus;
3use tokio::sync::oneshot::{channel, Receiver, Sender};
4
5#[derive(Debug)]
6pub struct ServerControl {
7    shutdown_sender: Option<Sender<String>>,
8    ready_receiver: Option<Receiver<Result<(), ServerError>>>,
9    done_receiver: Option<Receiver<Result<(), ServerError>>>,
10    pub current_status: ServerStatus,
11    pub last_error: Result<(), ServerError>,
12}
13
14impl ServerControl {
15    pub fn new() -> Self {
16        ServerControl {
17            shutdown_sender: None,
18            ready_receiver: None,
19            done_receiver: None,
20            current_status: ServerStatus::Stopped,
21            last_error: Ok({}),
22        }
23    }
24
25    pub fn get_ready(
26        &mut self,
27    ) -> Result<
28        (
29            Receiver<String>,
30            Sender<Result<(), ServerError>>,
31            Sender<Result<(), ServerError>>,
32        ),
33        ServerError,
34    > {
35        match self.current_status {
36            ServerStatus::Stopped => {
37                let (shutdown_sender, shutdown_receiver) = channel::<String>();
38                let (ready_sender, ready_receiver) = channel::<Result<(), ServerError>>();
39                let (done_sender, done_receiver) = channel::<Result<(), ServerError>>();
40                self.shutdown_sender = Some(shutdown_sender);
41                self.ready_receiver = Some(ready_receiver);
42                self.done_receiver = Some(done_receiver);
43                self.last_error = Ok({});
44                self.current_status = ServerStatus::Bootstrapping;
45                Ok((shutdown_receiver, ready_sender, done_sender))
46            }
47            other => Err(ServerError::new(
48                format!("invalid status {}", other).as_str(),
49            )),
50        }
51    }
52
53    pub fn stop(&mut self, msg: &str) -> Result<(), ServerError> {
54        match self.current_status {
55            ServerStatus::Running => {
56                self.current_status = ServerStatus::Terminating;
57                let ss = self.shutdown_sender.take().unwrap();
58                ss.send(msg.to_string()).unwrap();
59                Ok(())
60            }
61            other => Err(ServerError::new(
62                format!("invalid status {}", other).as_str(),
63            )),
64        }
65    }
66
67    pub fn update_status(&mut self) {
68        match self.current_status {
69            ServerStatus::Stopped => {}
70            ServerStatus::Bootstrapping => {
71                let mut trier = self.ready_receiver.take();
72                match &mut trier {
73                    Some(tr) => match &tr.try_recv() {
74                        Ok(e) => match e {
75                            Ok(()) => {
76                                self.current_status = ServerStatus::Running;
77                            }
78                            Err(ref err) => {
79                                self.last_error = Err(err.clone());
80                                self.current_status = ServerStatus::Stopped;
81                            }
82                        },
83                        Err(_) => (),
84                    },
85                    None => {}
86                }
87                self.ready_receiver = trier;
88            }
89            ServerStatus::Running => {}
90            ServerStatus::Terminating => {
91                let mut trier = self.done_receiver.take();
92                match &mut trier {
93                    Some(tr) => match &tr.try_recv() {
94                        Ok(e) => {
95                            match e {
96                                Ok(()) => (),
97                                Err(ref err) => {
98                                    self.last_error = Err(err.clone());
99                                }
100                            }
101                            self.current_status = ServerStatus::Stopped;
102                        }
103                        Err(_) => (),
104                    },
105                    None => {}
106                }
107                self.done_receiver = trier;
108            }
109        }
110    }
111}