Use `tokio::timer` instead of `tokio_timer`; use Kind pattern (#141)
This commit is contained in:
parent
5db8510892
commit
68d3f6c22e
|
@ -3,13 +3,17 @@
|
|||
//! If the response does not complete within the specified timeout, the response
|
||||
//! will be aborted.
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/tower-timeout/0.1.0")]
|
||||
#![deny(missing_debug_implementations, missing_docs)]
|
||||
#![cfg_attr(test, deny(warnings))]
|
||||
|
||||
extern crate futures;
|
||||
extern crate tower_service;
|
||||
extern crate tokio_timer;
|
||||
|
||||
use futures::{Future, Poll, Async};
|
||||
use tower_service::Service;
|
||||
use tokio_timer::{clock, Delay};
|
||||
use tokio_timer::{clock, Delay, Error as TimerError};
|
||||
|
||||
use std::{error, fmt};
|
||||
use std::time::Duration;
|
||||
|
@ -23,12 +27,19 @@ pub struct Timeout<T> {
|
|||
|
||||
/// Errors produced by `Timeout`.
|
||||
#[derive(Debug)]
|
||||
pub enum Error<T> {
|
||||
/// The inner service produced an error
|
||||
pub struct Error<T>(Kind<T>);
|
||||
|
||||
/// Timeout error variants
|
||||
#[derive(Debug)]
|
||||
enum Kind<T> {
|
||||
/// Inner value returned an error
|
||||
Inner(T),
|
||||
|
||||
/// The request did not complete within the specified timeout.
|
||||
Timeout,
|
||||
/// The timeout elapsed.
|
||||
Elapsed,
|
||||
|
||||
/// Timer returned an error.
|
||||
Timer(TimerError),
|
||||
}
|
||||
|
||||
/// `Timeout` response future
|
||||
|
@ -41,6 +52,7 @@ pub struct ResponseFuture<T> {
|
|||
// ===== impl Timeout =====
|
||||
|
||||
impl<T> Timeout<T> {
|
||||
/// Creates a new Timeout
|
||||
pub fn new(inner: T, timeout: Duration) -> Self {
|
||||
Timeout {
|
||||
inner,
|
||||
|
@ -59,7 +71,9 @@ where
|
|||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
self.inner.poll_ready()
|
||||
.map_err(Error::Inner)
|
||||
.map_err(|e| {
|
||||
Error(Kind::Inner(e))
|
||||
})
|
||||
}
|
||||
|
||||
fn call(&mut self, request: Request) -> Self::Future {
|
||||
|
@ -83,19 +97,18 @@ where T: Future,
|
|||
match self.response.poll() {
|
||||
Ok(Async::Ready(v)) => return Ok(Async::Ready(v)),
|
||||
Ok(Async::NotReady) => {}
|
||||
Err(e) => return Err(Error::Inner(e)),
|
||||
Err(e) => return Err(Error(Kind::Inner(e))),
|
||||
}
|
||||
|
||||
// Now check the sleep
|
||||
match self.sleep.poll() {
|
||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
||||
Ok(Async::Ready(_)) => Err(Error::Timeout),
|
||||
Err(_) => Err(Error::Timeout),
|
||||
Ok(Async::Ready(_)) => Err(Error(Kind::Elapsed)),
|
||||
Err(e) => Err(Error(Kind::Timer(e))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ===== impl Error =====
|
||||
|
||||
impl<T> fmt::Display for Error<T>
|
||||
|
@ -103,30 +116,95 @@ where
|
|||
T: fmt::Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::Inner(ref why) => fmt::Display::fmt(why, f),
|
||||
Error::Timeout => f.pad("request timed out"),
|
||||
match self.0 {
|
||||
Kind::Inner(ref why) => fmt::Display::fmt(why, f),
|
||||
Kind::Elapsed => f.pad("request timed out"),
|
||||
Kind::Timer(ref why) => fmt::Display::fmt(why, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> error::Error for Error<T>
|
||||
where
|
||||
T: error::Error,
|
||||
T: error::Error + 'static,
|
||||
{
|
||||
fn cause(&self) -> Option<&error::Error> {
|
||||
if let Error::Inner(ref why) = *self {
|
||||
fn description(&self) -> &str {
|
||||
match self.0 {
|
||||
Kind::Inner(ref e) => e.description(),
|
||||
Kind::Elapsed => "request timed out",
|
||||
Kind::Timer(ref e) => e.description(),
|
||||
}
|
||||
}
|
||||
|
||||
fn source(&self) -> Option<&(error::Error + 'static)> {
|
||||
let kind = &self.0;
|
||||
if let Kind::Inner(ref why) = kind {
|
||||
Some(why)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::Inner(_) => "inner service error",
|
||||
Error::Timeout => "request timed out",
|
||||
// ===== impl Error =====
|
||||
|
||||
impl<T> Error<T> {
|
||||
/// Create a new `Error` representing the inner value completing with `Err`.
|
||||
pub fn inner(err: T) -> Error<T> {
|
||||
Error(Kind::Inner(err))
|
||||
}
|
||||
|
||||
/// Returns `true` if the error was caused by the inner value completing
|
||||
/// with `Err`.
|
||||
pub fn is_inner(&self) -> bool {
|
||||
match self.0 {
|
||||
Kind::Inner(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Consumes `self`, returning the inner future error.
|
||||
pub fn into_inner(self) -> Option<T> {
|
||||
match self.0 {
|
||||
Kind::Inner(err) => Some(err),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new `Error` representing the inner value not completing before
|
||||
/// the deadline is reached.
|
||||
pub fn elapsed() -> Error<T> {
|
||||
Error(Kind::Elapsed)
|
||||
}
|
||||
|
||||
/// Returns `true` if the error was caused by the inner value not completing
|
||||
/// before the deadline is reached.
|
||||
pub fn is_elapsed(&self) -> bool {
|
||||
match self.0 {
|
||||
Kind::Elapsed => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new `Error` representing an error encountered by the timer
|
||||
/// implementation
|
||||
pub fn timer(err: TimerError) -> Error<T> {
|
||||
Error(Kind::Timer(err))
|
||||
}
|
||||
|
||||
/// Returns `true` if the error was caused by the timer.
|
||||
pub fn is_timer(&self) -> bool {
|
||||
match self.0 {
|
||||
Kind::Timer(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Consumes `self`, returning the error raised by the timer implementation.
|
||||
pub fn into_timer(self) -> Option<TimerError> {
|
||||
match self.0 {
|
||||
Kind::Timer(err) => Some(err),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue