From dfb3faa9902f1c407e475721be7e174eefae2b80 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sat, 29 Jan 2022 21:26:38 +0000 Subject: [PATCH] move timerstate to own file --- actix-http/Cargo.toml | 1 + actix-http/examples/bench.rs | 24 +++++++++ actix-http/src/h1/dispatcher.rs | 95 +-------------------------------- actix-http/src/h1/mod.rs | 1 + actix-http/src/h1/timer.rs | 80 +++++++++++++++++++++++++++ 5 files changed, 108 insertions(+), 93 deletions(-) create mode 100644 actix-http/examples/bench.rs create mode 100644 actix-http/src/h1/timer.rs diff --git a/actix-http/Cargo.toml b/actix-http/Cargo.toml index e93d1b7af..11bfa7a1a 100644 --- a/actix-http/Cargo.toml +++ b/actix-http/Cargo.toml @@ -92,6 +92,7 @@ criterion = { version = "0.3", features = ["html_reports"] } env_logger = "0.9" futures-util = { version = "0.3.7", default-features = false, features = ["alloc"] } memchr = "2.4" +once_cell = "1.9" rcgen = "0.8" regex = "1.3" rustls-pemfile = "0.2" diff --git a/actix-http/examples/bench.rs b/actix-http/examples/bench.rs new file mode 100644 index 000000000..38349b121 --- /dev/null +++ b/actix-http/examples/bench.rs @@ -0,0 +1,24 @@ +use std::{convert::Infallible, io}; + +use actix_http::{HttpService, Request, Response, StatusCode}; +use actix_server::Server; +use once_cell::sync::Lazy; + +static STR: Lazy = Lazy::new(|| "HELLO WORLD ".repeat(100)); + +#[actix_rt::main] +async fn main() -> io::Result<()> { + Server::build() + .bind("dispatcher-benchmark", ("127.0.0.1", 8080), || { + HttpService::build() + .finish(|_: Request| async move { + let mut res = Response::build(StatusCode::OK); + Ok::<_, Infallible>(res.body(&**STR)) + }) + .tcp() + })? + // limiting number of workers so that bench client is not sharing as many resources + .workers(4) + .run() + .await +} diff --git a/actix-http/src/h1/dispatcher.rs b/actix-http/src/h1/dispatcher.rs index 2e8d39def..2c05a484f 100644 --- a/actix-http/src/h1/dispatcher.rs +++ b/actix-http/src/h1/dispatcher.rs @@ -9,7 +9,7 @@ use std::{ }; use actix_codec::{AsyncRead, AsyncWrite, Decoder as _, Encoder as _, Framed, FramedParts}; -use actix_rt::time::{sleep_until, Instant, Sleep}; +use actix_rt::time::sleep_until; use actix_service::Service; use bitflags::bitflags; use bytes::{Buf, BytesMut}; @@ -28,6 +28,7 @@ use super::{ codec::Codec, decoder::MAX_BUFFER_SIZE, payload::{Payload, PayloadSender, PayloadStatus}, + timer::TimerState, Message, MessageType, }; @@ -165,98 +166,6 @@ pin_project! { } } -#[derive(Debug)] -enum TimerState { - Disabled, - Inactive, - Active { timer: Pin> }, -} - -impl TimerState { - fn new(enabled: bool) -> Self { - if enabled { - Self::Inactive - } else { - Self::Disabled - } - } - - fn is_enabled(&self) -> bool { - matches!(self, Self::Active { .. } | Self::Inactive) - } - - fn set(&mut self, timer: Sleep, line: u32) { - if !self.is_enabled() { - log::warn!("setting disabled timer from line {}", line); - } - - *self = Self::Active { - timer: Box::pin(timer), - }; - } - - #[allow(dead_code)] - fn reset(&mut self, deadline: Instant, line: u32) { - if !self.is_enabled() { - log::warn!("resetting disabled timer from line {}", line); - } - - match self { - TimerState::Active { timer } => { - let _ = timer.as_mut().reset(deadline); - } - - _ => self.set(sleep_until(deadline), line), - } - } - - fn set_and_init(&mut self, cx: &mut Context<'_>, timer: Sleep, line: u32) { - self.set(timer, line); - self.init(cx); - } - - fn clear(&mut self, line: u32) { - if !self.is_enabled() { - log::warn!("trying to clear a disabled timer from line {}", line); - } - - if matches!(self, Self::Inactive) { - log::warn!("trying to clear an inactive timer from line {}", line); - } - - *self = Self::Inactive; - } - - fn init(&mut self, cx: &mut Context<'_>) { - if let TimerState::Active { timer } = self { - let _ = timer.as_mut().poll(cx); - } - } -} - -impl fmt::Display for TimerState { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - TimerState::Disabled => f.write_str("timer is disabled"), - TimerState::Inactive => f.write_str("timer is inactive"), - TimerState::Active { timer } => { - let deadline = timer.deadline(); - let now = Instant::now(); - - if deadline < now { - f.write_str("timer is active and has reached deadline") - } else { - write!( - f, - "timer is active and due to expire in {} milliseconds", - ((deadline - now).as_secs_f32() * 1000.0) - ) - } - } - } - } -} - enum DispatcherMessage { Item(Request), Upgrade(Request), diff --git a/actix-http/src/h1/mod.rs b/actix-http/src/h1/mod.rs index 662a1ef98..858cf542a 100644 --- a/actix-http/src/h1/mod.rs +++ b/actix-http/src/h1/mod.rs @@ -13,6 +13,7 @@ mod encoder; mod expect; mod payload; mod service; +mod timer; mod upgrade; mod utils; diff --git a/actix-http/src/h1/timer.rs b/actix-http/src/h1/timer.rs new file mode 100644 index 000000000..29b3e2f75 --- /dev/null +++ b/actix-http/src/h1/timer.rs @@ -0,0 +1,80 @@ +use std::{fmt, future::Future, pin::Pin, task::Context}; + +use actix_rt::time::{Instant, Sleep}; + +#[derive(Debug)] +pub(super) enum TimerState { + Disabled, + Inactive, + Active { timer: Pin> }, +} + +impl TimerState { + pub(super) fn new(enabled: bool) -> Self { + if enabled { + Self::Inactive + } else { + Self::Disabled + } + } + + pub(super) fn is_enabled(&self) -> bool { + matches!(self, Self::Active { .. } | Self::Inactive) + } + + pub(super) fn set(&mut self, timer: Sleep, line: u32) { + if !self.is_enabled() { + log::warn!("setting disabled timer from line {}", line); + } + + *self = Self::Active { + timer: Box::pin(timer), + }; + } + + pub(super) fn set_and_init(&mut self, cx: &mut Context<'_>, timer: Sleep, line: u32) { + self.set(timer, line); + self.init(cx); + } + + pub(super) fn clear(&mut self, line: u32) { + if !self.is_enabled() { + log::warn!("trying to clear a disabled timer from line {}", line); + } + + if matches!(self, Self::Inactive) { + log::warn!("trying to clear an inactive timer from line {}", line); + } + + *self = Self::Inactive; + } + + pub(super) fn init(&mut self, cx: &mut Context<'_>) { + if let TimerState::Active { timer } = self { + let _ = timer.as_mut().poll(cx); + } + } +} + +impl fmt::Display for TimerState { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + TimerState::Disabled => f.write_str("timer is disabled"), + TimerState::Inactive => f.write_str("timer is inactive"), + TimerState::Active { timer } => { + let deadline = timer.deadline(); + let now = Instant::now(); + + if deadline < now { + f.write_str("timer is active and has reached deadline") + } else { + write!( + f, + "timer is active and due to expire in {} milliseconds", + ((deadline - now).as_secs_f32() * 1000.0) + ) + } + } + } + } +}