mirror of https://github.com/fafhrd91/actix-net
Add pause flag for Accept
This commit is contained in:
parent
5961eb892e
commit
ac78583fb5
|
@ -83,7 +83,7 @@ struct Accept {
|
||||||
handles: Vec<WorkerHandle>,
|
handles: Vec<WorkerHandle>,
|
||||||
srv: Server,
|
srv: Server,
|
||||||
next: usize,
|
next: usize,
|
||||||
backpressure: bool,
|
state: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function defines errors that are per-connection. Which basically
|
/// This function defines errors that are per-connection. Which basically
|
||||||
|
@ -154,7 +154,7 @@ impl Accept {
|
||||||
handles,
|
handles,
|
||||||
srv,
|
srv,
|
||||||
next: 0,
|
next: 0,
|
||||||
backpressure: false,
|
state: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
(accept, sockets)
|
(accept, sockets)
|
||||||
|
@ -190,13 +190,17 @@ impl Accept {
|
||||||
// from backpressure.
|
// from backpressure.
|
||||||
Some(WakerInterest::WorkerAvailable) => {
|
Some(WakerInterest::WorkerAvailable) => {
|
||||||
drop(guard);
|
drop(guard);
|
||||||
|
if !self.pause() {
|
||||||
self.maybe_backpressure(&mut sockets, false);
|
self.maybe_backpressure(&mut sockets, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// a new worker thread is made and it's handle would be added to Accept
|
// a new worker thread is made and it's handle would be added to Accept
|
||||||
Some(WakerInterest::Worker(handle)) => {
|
Some(WakerInterest::Worker(handle)) => {
|
||||||
drop(guard);
|
drop(guard);
|
||||||
// maybe we want to recover from a backpressure.
|
// maybe we want to recover from a backpressure.
|
||||||
|
if !self.pause() {
|
||||||
self.maybe_backpressure(&mut sockets, false);
|
self.maybe_backpressure(&mut sockets, false);
|
||||||
|
}
|
||||||
self.handles.push(handle);
|
self.handles.push(handle);
|
||||||
}
|
}
|
||||||
// got timer interest and it's time to try register socket(s) again
|
// got timer interest and it's time to try register socket(s) again
|
||||||
|
@ -206,16 +210,24 @@ impl Accept {
|
||||||
}
|
}
|
||||||
Some(WakerInterest::Pause) => {
|
Some(WakerInterest::Pause) => {
|
||||||
drop(guard);
|
drop(guard);
|
||||||
|
if !self.pause() {
|
||||||
|
self.set_pause(true);
|
||||||
self.deregister_all(&mut sockets);
|
self.deregister_all(&mut sockets);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Some(WakerInterest::Resume) => {
|
Some(WakerInterest::Resume) => {
|
||||||
drop(guard);
|
drop(guard);
|
||||||
sockets.iter_mut().for_each(|(token, info)| {
|
sockets.iter_mut().for_each(|(token, info)| {
|
||||||
self.register_logged(token, info);
|
self.register_logged(token, info);
|
||||||
});
|
});
|
||||||
|
self.set_pause(false);
|
||||||
}
|
}
|
||||||
Some(WakerInterest::Stop) => {
|
Some(WakerInterest::Stop) => {
|
||||||
return self.deregister_all(&mut sockets);
|
if !self.pause() {
|
||||||
|
self.deregister_all(&mut sockets);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// waker queue is drained
|
// waker queue is drained
|
||||||
None => {
|
None => {
|
||||||
|
@ -245,7 +257,7 @@ impl Accept {
|
||||||
|
|
||||||
if now < inst {
|
if now < inst {
|
||||||
info.timeout = Some(inst);
|
info.timeout = Some(inst);
|
||||||
} else if !self.backpressure {
|
} else if !self.backpressure() {
|
||||||
self.register_logged(token, info);
|
self.register_logged(token, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,12 +298,8 @@ impl Accept {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deregister(&self, info: &mut ServerSocketInfo) -> io::Result<()> {
|
|
||||||
self.poll.registry().deregister(&mut info.lst)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deregister_logged(&self, info: &mut ServerSocketInfo) {
|
fn deregister_logged(&self, info: &mut ServerSocketInfo) {
|
||||||
match self.deregister(info) {
|
match self.poll.registry().deregister(&mut info.lst) {
|
||||||
Ok(_) => info!("Paused accepting connections on {}", info.addr),
|
Ok(_) => info!("Paused accepting connections on {}", info.addr),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Can not deregister server socket {}", e)
|
error!("Can not deregister server socket {}", e)
|
||||||
|
@ -320,8 +328,8 @@ impl Accept {
|
||||||
|
|
||||||
fn maybe_backpressure(&mut self, sockets: &mut Slab<ServerSocketInfo>, on: bool) {
|
fn maybe_backpressure(&mut self, sockets: &mut Slab<ServerSocketInfo>, on: bool) {
|
||||||
// Only operate when server is in a different backpressure than the given flag.
|
// Only operate when server is in a different backpressure than the given flag.
|
||||||
if self.backpressure != on {
|
if self.backpressure() != on {
|
||||||
self.backpressure = on;
|
self.set_backpressure(on);
|
||||||
sockets
|
sockets
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
// Only operate on sockets without associated timeout.
|
// Only operate on sockets without associated timeout.
|
||||||
|
@ -339,7 +347,7 @@ impl Accept {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn accept_one(&mut self, sockets: &mut Slab<ServerSocketInfo>, mut conn: Conn) {
|
fn accept_one(&mut self, sockets: &mut Slab<ServerSocketInfo>, mut conn: Conn) {
|
||||||
if self.backpressure {
|
if self.backpressure() {
|
||||||
// send_connection would remove fault worker from handles.
|
// send_connection would remove fault worker from handles.
|
||||||
// worst case here is conn get dropped after all handles are gone.
|
// worst case here is conn get dropped after all handles are gone.
|
||||||
while !self.handles.is_empty() {
|
while !self.handles.is_empty() {
|
||||||
|
@ -426,7 +434,9 @@ impl Accept {
|
||||||
error!("Error accepting connection: {}", e);
|
error!("Error accepting connection: {}", e);
|
||||||
|
|
||||||
// deregister listener temporary
|
// deregister listener temporary
|
||||||
|
if !self.backpressure() {
|
||||||
self.deregister_logged(info);
|
self.deregister_logged(info);
|
||||||
|
}
|
||||||
|
|
||||||
// sleep after error. write the timeout to socket info as later
|
// sleep after error. write the timeout to socket info as later
|
||||||
// the poll would need it mark which socket and when it's
|
// the poll would need it mark which socket and when it's
|
||||||
|
@ -446,3 +456,38 @@ impl Accept {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// bit flag for marking server in pause state;
|
||||||
|
const PAUSE: u8 = 1;
|
||||||
|
/// bit flag for marking server in back pressure state.
|
||||||
|
const BACK_PRESSURE: u8 = 1 << 1;
|
||||||
|
|
||||||
|
impl Accept {
|
||||||
|
fn backpressure(&self) -> bool {
|
||||||
|
self.state(BACK_PRESSURE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pause(&self) -> bool {
|
||||||
|
self.state(PAUSE)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_backpressure(&mut self, on: bool) {
|
||||||
|
self.set_state(BACK_PRESSURE, on);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_pause(&mut self, on: bool) {
|
||||||
|
self.set_state(PAUSE, on);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn state(&self, state: u8) -> bool {
|
||||||
|
self.state & state != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_state(&mut self, state: u8, on: bool) {
|
||||||
|
if on {
|
||||||
|
self.state |= state;
|
||||||
|
} else {
|
||||||
|
self.state ^= state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue