use crate::server_error::ServerError;
use crate::server_status::ServerStatus;
use tokio::sync::oneshot::{channel, Receiver, Sender};
#[derive(Debug)]
pub struct ServerControl {
shutdown_sender: Option<Sender<String>>,
ready_receiver: Option<Receiver<Result<(), ServerError>>>,
done_receiver: Option<Receiver<Result<(), ServerError>>>,
pub current_status: ServerStatus,
pub last_error: Result<(), ServerError>,
}
impl ServerControl {
pub fn new() -> Self {
ServerControl {
shutdown_sender: None,
ready_receiver: None,
done_receiver: None,
current_status: ServerStatus::Stopped,
last_error: Ok({}),
}
}
pub fn get_ready(
&mut self,
) -> Result<
(
Receiver<String>,
Sender<Result<(), ServerError>>,
Sender<Result<(), ServerError>>,
),
ServerError,
> {
match self.current_status {
ServerStatus::Stopped => {
let (shutdown_sender, shutdown_receiver) = channel::<String>();
let (ready_sender, ready_receiver) = channel::<Result<(), ServerError>>();
let (done_sender, done_receiver) = channel::<Result<(), ServerError>>();
self.shutdown_sender = Some(shutdown_sender);
self.ready_receiver = Some(ready_receiver);
self.done_receiver = Some(done_receiver);
self.last_error = Ok({});
self.current_status = ServerStatus::Bootstrapping;
Ok((shutdown_receiver, ready_sender, done_sender))
}
other => Err(ServerError::new(
format!("invalid status {}", other).as_str(),
)),
}
}
pub fn stop(&mut self, msg: &str) -> Result<(), ServerError> {
match self.current_status {
ServerStatus::Running => {
self.current_status = ServerStatus::Terminating;
let ss = self.shutdown_sender.take().unwrap();
ss.send(msg.to_string()).unwrap();
Ok(())
}
other => Err(ServerError::new(
format!("invalid status {}", other).as_str(),
)),
}
}
pub fn update_status(&mut self) {
match self.current_status {
ServerStatus::Stopped => {}
ServerStatus::Bootstrapping => {
let mut trier = self.ready_receiver.take();
match &mut trier {
Some(tr) => match &tr.try_recv() {
Ok(e) => match e {
Ok(()) => {
self.current_status = ServerStatus::Running;
}
Err(ref err) => {
self.last_error = Err(err.clone());
self.current_status = ServerStatus::Stopped;
}
},
Err(_) => (),
},
None => {}
}
self.ready_receiver = trier;
}
ServerStatus::Running => {}
ServerStatus::Terminating => {
let mut trier = self.done_receiver.take();
match &mut trier {
Some(tr) => match &tr.try_recv() {
Ok(e) => {
match e {
Ok(()) => (),
Err(ref err) => {
self.last_error = Err(err.clone());
}
}
self.current_status = ServerStatus::Stopped;
}
Err(_) => (),
},
None => {}
}
self.done_receiver = trier;
}
}
}
}