From d19a5e1ea1d373f5cc8591bb2a0d5d80d4742abe Mon Sep 17 00:00:00 2001 From: Josh Leeb-du Toit Date: Thu, 16 May 2019 19:17:18 +1000 Subject: [PATCH] Add ServerCommand::Restart and Command::Restart This PR creates a new `ServerCommand` and corresponding `Command` to restart server workers. Related to actix/actix-web#280 --- actix-server/src/accept.rs | 21 +++++++++++++++++++++ actix-server/src/builder.rs | 4 ++++ actix-server/src/server.rs | 8 ++++++++ 3 files changed, 33 insertions(+) diff --git a/actix-server/src/accept.rs b/actix-server/src/accept.rs index e02fb05f..f152e608 100644 --- a/actix-server/src/accept.rs +++ b/actix-server/src/accept.rs @@ -16,6 +16,7 @@ use super::Token; pub(crate) enum Command { Pause, Resume, + Restart, Stop, Worker(WorkerClient), } @@ -315,6 +316,26 @@ impl Accept { } } } + Command::Restart => { + for (token, info) in self.sockets.iter_mut() { + if let Err(err) = self.poll.deregister(&info.sock) { + error!("Can not restart server socket {}", err); + } + if let Err(err) = self.poll.reregister( + &info.sock, + mio::Token(token + DELTA), + mio::Ready::readable(), + mio::PollOpt::edge(), + ) { + error!("Can not restart socket accept process: {}", err); + } else { + info!( + "Accepting connections on {} has been restarted", + info.addr + ); + } + } + } Command::Stop => { for (_, info) in self.sockets.iter() { let _ = self.poll.deregister(&info.sock); diff --git a/actix-server/src/builder.rs b/actix-server/src/builder.rs index 7cd8bfab..bd70404e 100644 --- a/actix-server/src/builder.rs +++ b/actix-server/src/builder.rs @@ -287,6 +287,10 @@ impl ServerBuilder { self.accept.send(Command::Resume); let _ = tx.send(()); } + ServerCommand::Restart(tx) => { + self.accept.send(Command::Restart); + let _ = tx.send(()); + } ServerCommand::Signal(sig) => { // Signals support // Handle `SIGINT`, `SIGTERM`, `SIGQUIT` signals and stop actix system diff --git a/actix-server/src/server.rs b/actix-server/src/server.rs index f1d862c9..82219331 100644 --- a/actix-server/src/server.rs +++ b/actix-server/src/server.rs @@ -10,6 +10,7 @@ pub(crate) enum ServerCommand { WorkerDied(usize), Pause(oneshot::Sender<()>), Resume(oneshot::Sender<()>), + Restart(oneshot::Sender<()>), Signal(Signal), /// Whether to try and shut down gracefully Stop { @@ -56,6 +57,13 @@ impl Server { rx.map_err(|_| ()) } + /// Restart server + pub fn restart(&self) -> impl Future { + let (tx, rx) = oneshot::channel(); + let _ = self.0.unbounded_send(ServerCommand::Restart(tx)); + rx.map_err(|_| ()) + } + /// Stop incoming connection processing, stop all workers and exit. /// /// If server starts with `spawn()` method, then spawned thread get terminated.