2019-11-26 11:33:45 +01:00
|
|
|
use std::future::Future;
|
|
|
|
use std::pin::Pin;
|
|
|
|
use std::task::{Context, Poll};
|
|
|
|
|
2019-11-14 13:38:24 +01:00
|
|
|
use futures::channel::mpsc::UnboundedSender;
|
|
|
|
use futures::channel::oneshot;
|
2019-11-26 11:33:45 +01:00
|
|
|
use futures::FutureExt;
|
2018-12-10 06:51:35 +01:00
|
|
|
|
2018-12-11 06:06:54 +01:00
|
|
|
use crate::builder::ServerBuilder;
|
2019-11-14 13:38:24 +01:00
|
|
|
// use crate::signals::Signal;
|
2018-12-10 06:51:35 +01:00
|
|
|
|
2019-05-02 07:31:04 +02:00
|
|
|
#[derive(Debug)]
|
2018-12-10 06:51:35 +01:00
|
|
|
pub(crate) enum ServerCommand {
|
2019-11-14 13:38:24 +01:00
|
|
|
WorkerFaulted(usize),
|
2018-12-10 06:51:35 +01:00
|
|
|
Pause(oneshot::Sender<()>),
|
|
|
|
Resume(oneshot::Sender<()>),
|
2019-11-14 13:38:24 +01:00
|
|
|
// Signal(Signal),
|
2018-12-10 06:51:35 +01:00
|
|
|
/// Whether to try and shut down gracefully
|
|
|
|
Stop {
|
|
|
|
graceful: bool,
|
2018-12-11 06:06:54 +01:00
|
|
|
completion: Option<oneshot::Sender<()>>,
|
2018-12-10 06:51:35 +01:00
|
|
|
},
|
2019-11-26 11:33:45 +01:00
|
|
|
/// Notify of server stop
|
|
|
|
Notify(oneshot::Sender<()>),
|
2018-12-10 06:51:35 +01:00
|
|
|
}
|
|
|
|
|
2019-11-26 11:33:45 +01:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Server(
|
|
|
|
UnboundedSender<ServerCommand>,
|
|
|
|
Option<oneshot::Receiver<()>>,
|
|
|
|
);
|
2018-12-10 06:51:35 +01:00
|
|
|
|
|
|
|
impl Server {
|
|
|
|
pub(crate) fn new(tx: UnboundedSender<ServerCommand>) -> Self {
|
2019-11-26 11:33:45 +01:00
|
|
|
Server(tx, None)
|
2018-12-10 06:51:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Start server building process
|
|
|
|
pub fn build() -> ServerBuilder {
|
|
|
|
ServerBuilder::default()
|
|
|
|
}
|
|
|
|
|
2019-11-14 13:38:24 +01:00
|
|
|
// pub(crate) fn signal(&self, sig: Signal) {
|
|
|
|
// let _ = self.0.unbounded_send(ServerCommand::Signal(sig));
|
|
|
|
// }
|
2018-12-11 06:06:54 +01:00
|
|
|
|
2019-11-14 13:38:24 +01:00
|
|
|
pub(crate) fn worker_faulted(&self, idx: usize) {
|
|
|
|
let _ = self.0.unbounded_send(ServerCommand::WorkerFaulted(idx));
|
2018-12-10 06:51:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Pause accepting incoming connections
|
|
|
|
///
|
|
|
|
/// If socket contains some pending connection, they might be dropped.
|
|
|
|
/// All opened connection remains active.
|
2019-11-26 11:33:45 +01:00
|
|
|
pub fn pause(&self) -> impl Future<Output = ()> {
|
2018-12-10 06:51:35 +01:00
|
|
|
let (tx, rx) = oneshot::channel();
|
|
|
|
let _ = self.0.unbounded_send(ServerCommand::Pause(tx));
|
2019-11-26 11:33:45 +01:00
|
|
|
rx.map(|_| ())
|
2018-12-10 06:51:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Resume accepting incoming connections
|
2019-11-26 11:33:45 +01:00
|
|
|
pub fn resume(&self) -> impl Future<Output = ()> {
|
2018-12-10 06:51:35 +01:00
|
|
|
let (tx, rx) = oneshot::channel();
|
|
|
|
let _ = self.0.unbounded_send(ServerCommand::Resume(tx));
|
2019-11-26 11:33:45 +01:00
|
|
|
rx.map(|_| ())
|
2018-12-10 06:51:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Stop incoming connection processing, stop all workers and exit.
|
|
|
|
///
|
|
|
|
/// If server starts with `spawn()` method, then spawned thread get terminated.
|
2019-11-26 11:33:45 +01:00
|
|
|
pub fn stop(&self, graceful: bool) -> impl Future<Output = ()> {
|
2018-12-10 06:51:35 +01:00
|
|
|
let (tx, rx) = oneshot::channel();
|
|
|
|
let _ = self.0.unbounded_send(ServerCommand::Stop {
|
|
|
|
graceful,
|
2018-12-11 06:06:54 +01:00
|
|
|
completion: Some(tx),
|
2018-12-10 06:51:35 +01:00
|
|
|
});
|
2019-11-26 11:33:45 +01:00
|
|
|
rx.map(|_| ())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Clone for Server {
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
Self(self.0.clone(), None)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Future for Server {
|
|
|
|
type Output = ();
|
|
|
|
|
|
|
|
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
|
|
|
let this = self.get_mut();
|
|
|
|
|
|
|
|
if this.1.is_none() {
|
|
|
|
let (tx, rx) = oneshot::channel();
|
|
|
|
if this.0.unbounded_send(ServerCommand::Notify(tx)).is_err() {
|
|
|
|
return Poll::Ready(());
|
|
|
|
}
|
|
|
|
this.1 = Some(rx);
|
|
|
|
}
|
|
|
|
|
|
|
|
match Pin::new(this.1.as_mut().unwrap()).poll(cx) {
|
|
|
|
Poll::Pending => Poll::Pending,
|
|
|
|
Poll::Ready(Ok(_)) => Poll::Ready(()),
|
|
|
|
Poll::Ready(Err(_)) => Poll::Ready(()),
|
|
|
|
}
|
2018-12-10 06:51:35 +01:00
|
|
|
}
|
|
|
|
}
|