From 7a760f906355069c2fc07785e90f4840b95d0162 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 30 Mar 2021 03:09:35 +0100 Subject: [PATCH] remove timeout mod --- actix-utils/CHANGES.md | 1 + actix-utils/Cargo.toml | 6 - actix-utils/src/lib.rs | 2 +- actix-utils/src/timeout.rs | 259 ------------------------------------- 4 files changed, 2 insertions(+), 266 deletions(-) delete mode 100644 actix-utils/src/timeout.rs diff --git a/actix-utils/CHANGES.md b/actix-utils/CHANGES.md index 33876a33..64c38a2a 100644 --- a/actix-utils/CHANGES.md +++ b/actix-utils/CHANGES.md @@ -3,6 +3,7 @@ ## Unreleased - 2021-xx-xx * Moved `mpsc` to own crate `local-channel`. [#301] * Moved `task::LocalWaker` to own crate `local-waker`. [#301] +* Remove `timeout` module. [#301] * Expose `future` mod with `ready` and `poll_fn` helpers. [#301] * `SendError` inner field is now public. [#286] * Rename `Dispatcher::{get_sink => tx}`. [#286] diff --git a/actix-utils/Cargo.toml b/actix-utils/Cargo.toml index e9213eff..02bc3114 100644 --- a/actix-utils/Cargo.toml +++ b/actix-utils/Cargo.toml @@ -16,14 +16,8 @@ name = "actix_utils" path = "src/lib.rs" [dependencies] -actix-rt = { version = "2.0.0", default-features = false } -actix-service = "2.0.0-beta.5" - local-waker = "0.1" -log = "0.4" -pin-project-lite = "0.2.0" [dev-dependencies] actix-rt = "2.0.0" -futures-core = { version = "0.3.7", default-features = false, features = ["alloc"] } futures-util = { version = "0.3.7", default-features = false } diff --git a/actix-utils/src/lib.rs b/actix-utils/src/lib.rs index aff9f235..06f18032 100644 --- a/actix-utils/src/lib.rs +++ b/actix-utils/src/lib.rs @@ -1,5 +1,6 @@ //! Various network related services and utilities for the Actix ecosystem. +#![no_std] #![deny(rust_2018_idioms, nonstandard_style)] #![allow(clippy::type_complexity)] #![doc(html_logo_url = "https://actix.rs/img/logo.png")] @@ -9,4 +10,3 @@ extern crate alloc; pub mod counter; pub mod future; -pub mod timeout; diff --git a/actix-utils/src/timeout.rs b/actix-utils/src/timeout.rs deleted file mode 100644 index affcd62b..00000000 --- a/actix-utils/src/timeout.rs +++ /dev/null @@ -1,259 +0,0 @@ -//! Service that applies a timeout to requests. -//! -//! If the response does not complete within the specified timeout, the response will be aborted. - -use core::{ - fmt, - future::Future, - marker::PhantomData, - pin::Pin, - task::{Context, Poll}, - time, -}; - -use actix_rt::time::{sleep, Sleep}; -use actix_service::{IntoService, Service, Transform}; -use pin_project_lite::pin_project; - -/// Applies a timeout to requests. -#[derive(Debug)] -pub struct Timeout { - timeout: time::Duration, - _t: PhantomData, -} - -/// Service or timeout error. -pub enum TimeoutError { - /// Inner service error. - Service(E), - - /// Timeout during service call. - Timeout, -} - -impl From for TimeoutError { - fn from(err: E) -> Self { - TimeoutError::Service(err) - } -} - -impl fmt::Debug for TimeoutError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - TimeoutError::Service(e) => write!(f, "TimeoutError::Service({:?})", e), - TimeoutError::Timeout => write!(f, "TimeoutError::Timeout"), - } - } -} - -impl fmt::Display for TimeoutError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - TimeoutError::Service(err) => err.fmt(f), - TimeoutError::Timeout => write!(f, "timeout during service call"), - } - } -} - -impl PartialEq for TimeoutError { - fn eq(&self, other: &TimeoutError) -> bool { - match self { - TimeoutError::Service(e1) => match other { - TimeoutError::Service(e2) => e1 == e2, - TimeoutError::Timeout => false, - }, - TimeoutError::Timeout => matches!(other, TimeoutError::Timeout), - } - } -} - -impl Timeout { - pub fn new(timeout: time::Duration) -> Self { - Timeout { - timeout, - _t: PhantomData, - } - } -} - -impl Clone for Timeout { - fn clone(&self) -> Self { - Timeout::new(self.timeout) - } -} - -impl Transform for Timeout -where - S: Service, -{ - type Response = S::Response; - type Error = TimeoutError; - type Transform = TimeoutService; - type InitError = E; - type Future = TimeoutFuture; - - fn new_transform(&self, service: S) -> Self::Future { - let service = TimeoutService { - service, - timeout: self.timeout, - _phantom: PhantomData, - }; - - TimeoutFuture { - service: Some(service), - _err: PhantomData, - } - } -} - -pub struct TimeoutFuture { - service: Option, - _err: PhantomData, -} - -impl Unpin for TimeoutFuture {} - -impl Future for TimeoutFuture { - type Output = Result; - - fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll { - Poll::Ready(Ok(self.get_mut().service.take().unwrap())) - } -} - -/// Applies a timeout to requests. -#[derive(Debug, Clone)] -pub struct TimeoutService { - service: S, - timeout: time::Duration, - _phantom: PhantomData, -} - -impl TimeoutService -where - S: Service, -{ - pub fn new(timeout: time::Duration, service: U) -> Self - where - U: IntoService, - { - TimeoutService { - timeout, - service: service.into_service(), - _phantom: PhantomData, - } - } -} - -impl Service for TimeoutService -where - S: Service, -{ - type Response = S::Response; - type Error = TimeoutError; - type Future = TimeoutServiceResponse; - - actix_service::forward_ready!(service); - - fn call(&self, request: Req) -> Self::Future { - TimeoutServiceResponse { - fut: self.service.call(request), - sleep: sleep(self.timeout), - } - } -} - -pin_project! { - /// `TimeoutService` response future. - #[derive(Debug)] - pub struct TimeoutServiceResponse - where - S: Service - { - #[pin] - fut: S::Future, - #[pin] - sleep: Sleep, - } -} - -impl Future for TimeoutServiceResponse -where - S: Service, -{ - type Output = Result>; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let this = self.project(); - - // first try polling the future - if let Poll::Ready(res) = this.fut.poll(cx) { - return match res { - Ok(v) => Poll::Ready(Ok(v)), - Err(e) => Poll::Ready(Err(TimeoutError::Service(e))), - }; - } - - // now check the sleep - this.sleep.poll(cx).map(|_| Err(TimeoutError::Timeout)) - } -} - -#[cfg(test)] -mod tests { - use core::time::Duration; - - use super::*; - use actix_service::{apply, fn_factory, Service, ServiceFactory}; - use futures_core::future::LocalBoxFuture; - - struct SleepService(Duration); - - impl Service<()> for SleepService { - type Response = (); - type Error = (); - type Future = LocalBoxFuture<'static, Result<(), ()>>; - - actix_service::always_ready!(); - - fn call(&self, _: ()) -> Self::Future { - let sleep = actix_rt::time::sleep(self.0); - Box::pin(async move { - sleep.await; - Ok(()) - }) - } - } - - #[actix_rt::test] - async fn test_success() { - let resolution = Duration::from_millis(100); - let wait_time = Duration::from_millis(50); - - let timeout = TimeoutService::new(resolution, SleepService(wait_time)); - assert_eq!(timeout.call(()).await, Ok(())); - } - - #[actix_rt::test] - async fn test_timeout() { - let resolution = Duration::from_millis(100); - let wait_time = Duration::from_millis(500); - - let timeout = TimeoutService::new(resolution, SleepService(wait_time)); - assert_eq!(timeout.call(()).await, Err(TimeoutError::Timeout)); - } - - #[actix_rt::test] - async fn test_timeout_new_service() { - let resolution = Duration::from_millis(100); - let wait_time = Duration::from_millis(500); - - let timeout = apply( - Timeout::new(resolution), - fn_factory(|| async { Ok::<_, ()>(SleepService(wait_time)) }), - ); - let srv = timeout.new_service(&()).await.unwrap(); - - assert_eq!(srv.call(()).await, Err(TimeoutError::Timeout)); - } -}