1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2025-01-04 14:28:50 +00: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,51 +645,50 @@ 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 // when a branch is not explicit return early it's meant to fall through
// and return as Ok(())
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) {
if let Some(interval) = this.codec.config().client_disconnect_timer() { if let Some(deadline) = this.codec.config().client_disconnect_timer()
this.ka_timer.set(Some(sleep_until(interval))); {
// write client disconnect time out and poll again to
// go into Some<Pin<&mut Sleep>> branch
this.ka_timer.set(Some(sleep_until(deadline)));
return self.poll_keepalive(cx);
} else { } else {
this.flags.insert(Flags::READ_DISCONNECT); this.flags.insert(Flags::READ_DISCONNECT);
if let Some(mut payload) = this.payload.take() { if let Some(mut payload) = this.payload.take() {
payload.set_error(PayloadError::Incomplete(None)); payload.set_error(PayloadError::Incomplete(None));
} }
return Ok(());
}
} else {
return Ok(());
} }
} }
}
match this.ka_timer.as_mut().as_pin_mut().unwrap().poll(cx) { Some(mut timer) => {
Poll::Ready(()) => { // only operate when keep-alive timer is resolved.
// if we get timeout during shutdown, drop connection if timer.as_mut().poll(cx).is_ready() {
// got timeout during shutdown, drop connection
if this.flags.contains(Flags::SHUTDOWN) { if this.flags.contains(Flags::SHUTDOWN) {
return Err(DispatchError::DisconnectTimeout); return Err(DispatchError::DisconnectTimeout);
} else if this.ka_timer.as_mut().as_pin_mut().unwrap().deadline() // exceed deadline. check for any outstanding tasks
>= *this.ka_expire } else if timer.deadline() >= *this.ka_expire {
{ // have no task at hand.
// check for any outstanding tasks
if this.state.is_empty() && this.write_buf.is_empty() { if this.state.is_empty() && this.write_buf.is_empty() {
if this.flags.contains(Flags::STARTED) { if this.flags.contains(Flags::STARTED) {
trace!("Keep-alive timeout, close connection"); trace!("Keep-alive timeout, close connection");
this.flags.insert(Flags::SHUTDOWN); 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 { } else {
// no shutdown timeout, drop socket // no shutdown timeout, drop socket
this.flags.insert(Flags::WRITE_DISCONNECT); this.flags.insert(Flags::WRITE_DISCONNECT);
return Ok(());
} }
} else { } else {
// timeout on first request (slow request) return 408 // timeout on first request (slow request) return 408
@ -699,29 +698,29 @@ where
Response::RequestTimeout().finish().drop_body(), Response::RequestTimeout().finish().drop_body(),
ResponseBody::Other(Body::Empty), ResponseBody::Other(Body::Empty),
); );
this = self.as_mut().project(); this = self.project();
} else { } else {
trace!("Keep-alive connection timeout"); trace!("Keep-alive connection timeout");
} }
this.flags.insert(Flags::STARTED | Flags::SHUTDOWN); this.flags.insert(Flags::STARTED | Flags::SHUTDOWN);
this.state.set(State::None); this.state.set(State::None);
} }
// still have unfinished task. try to reset and register keep-alive.
} else if let Some(deadline) = } else if let Some(deadline) =
this.codec.config().keep_alive_expire() 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.
} else if let Some(mut timer) = this.ka_timer.as_mut().as_pin_mut() { // reset and register for later wakeup.
} else {
timer.as_mut().reset(*this.ka_expire); timer.as_mut().reset(*this.ka_expire);
let _ = timer.poll(cx); let _ = timer.poll(cx);
} }
} }
Poll::Pending => {}
} }
}
Ok(()) Ok(())
} }
} }