1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-01-19 06:04:40 +01:00

Refactor poll_keepalive for readability (#1901)

This commit is contained in:
fakeshadow 2021-01-16 08:15:06 +08:00 committed by GitHub
parent da69bb4d12
commit 1c95fc2654
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -645,83 +645,82 @@ where
cx: &mut Context<'_>, cx: &mut Context<'_>,
) -> Result<(), DispatchError> { ) -> Result<(), DispatchError> {
let mut this = self.as_mut().project(); let mut this = self.as_mut().project();
if this.ka_timer.is_none() {
// shutdown timeout
if this.flags.contains(Flags::SHUTDOWN) {
if let Some(interval) = this.codec.config().client_disconnect_timer() {
this.ka_timer.set(Some(sleep_until(interval)));
} else {
this.flags.insert(Flags::READ_DISCONNECT);
if let Some(mut payload) = this.payload.take() {
payload.set_error(PayloadError::Incomplete(None));
}
return Ok(());
}
} else {
return Ok(());
}
}
match this.ka_timer.as_mut().as_pin_mut().unwrap().poll(cx) { // when a branch is not explicit return early it's meant to fall through
Poll::Ready(()) => { // and return as Ok(())
// if we get timeout during shutdown, drop connection match this.ka_timer.as_mut().as_pin_mut() {
None => {
// conditionally go into shutdown timeout
if this.flags.contains(Flags::SHUTDOWN) { if this.flags.contains(Flags::SHUTDOWN) {
return Err(DispatchError::DisconnectTimeout); if let Some(deadline) = this.codec.config().client_disconnect_timer()
} else if this.ka_timer.as_mut().as_pin_mut().unwrap().deadline() {
>= *this.ka_expire // write client disconnect time out and poll again to
{ // go into Some<Pin<&mut Sleep>> branch
// check for any outstanding tasks this.ka_timer.set(Some(sleep_until(deadline)));
if this.state.is_empty() && this.write_buf.is_empty() { return self.poll_keepalive(cx);
if this.flags.contains(Flags::STARTED) { } else {
trace!("Keep-alive timeout, close connection"); this.flags.insert(Flags::READ_DISCONNECT);
this.flags.insert(Flags::SHUTDOWN); if let Some(mut payload) = this.payload.take() {
payload.set_error(PayloadError::Incomplete(None));
}
}
}
}
Some(mut timer) => {
// only operate when keep-alive timer is resolved.
if timer.as_mut().poll(cx).is_ready() {
// got timeout during shutdown, drop connection
if this.flags.contains(Flags::SHUTDOWN) {
return Err(DispatchError::DisconnectTimeout);
// exceed deadline. check for any outstanding tasks
} else if timer.deadline() >= *this.ka_expire {
// have no task at hand.
if this.state.is_empty() && this.write_buf.is_empty() {
if this.flags.contains(Flags::STARTED) {
trace!("Keep-alive timeout, close connection");
this.flags.insert(Flags::SHUTDOWN);
// start shutdown timer // start shutdown timeout
if let Some(deadline) = if let Some(deadline) =
this.codec.config().client_disconnect_timer() this.codec.config().client_disconnect_timer()
{
if let Some(mut timer) =
this.ka_timer.as_mut().as_pin_mut()
{ {
timer.as_mut().reset(deadline); timer.as_mut().reset(deadline);
let _ = timer.poll(cx); let _ = timer.poll(cx);
} else {
// no shutdown timeout, drop socket
this.flags.insert(Flags::WRITE_DISCONNECT);
} }
} else { } else {
// no shutdown timeout, drop socket // timeout on first request (slow request) return 408
this.flags.insert(Flags::WRITE_DISCONNECT); if !this.flags.contains(Flags::STARTED) {
return Ok(()); trace!("Slow request timeout");
let _ = self.as_mut().send_response(
Response::RequestTimeout().finish().drop_body(),
ResponseBody::Other(Body::Empty),
);
this = self.project();
} else {
trace!("Keep-alive connection timeout");
}
this.flags.insert(Flags::STARTED | Flags::SHUTDOWN);
this.state.set(State::None);
} }
} else { // still have unfinished task. try to reset and register keep-alive.
// timeout on first request (slow request) return 408 } else if let Some(deadline) =
if !this.flags.contains(Flags::STARTED) { this.codec.config().keep_alive_expire()
trace!("Slow request timeout"); {
let _ = self.as_mut().send_response(
Response::RequestTimeout().finish().drop_body(),
ResponseBody::Other(Body::Empty),
);
this = self.as_mut().project();
} else {
trace!("Keep-alive connection timeout");
}
this.flags.insert(Flags::STARTED | Flags::SHUTDOWN);
this.state.set(State::None);
}
} else if let Some(deadline) =
this.codec.config().keep_alive_expire()
{
if let Some(mut timer) = this.ka_timer.as_mut().as_pin_mut() {
timer.as_mut().reset(deadline); timer.as_mut().reset(deadline);
let _ = timer.poll(cx); let _ = timer.poll(cx);
} }
// timer resolved but still have not met the keep-alive expire deadline.
// reset and register for later wakeup.
} else {
timer.as_mut().reset(*this.ka_expire);
let _ = timer.poll(cx);
} }
} else if let Some(mut timer) = this.ka_timer.as_mut().as_pin_mut() {
timer.as_mut().reset(*this.ka_expire);
let _ = timer.poll(cx);
} }
} }
Poll::Pending => {}
} }
Ok(()) Ok(())
} }
} }