move shared fail struct into own crate

This commit is contained in:
Sam Rijs 2018-02-24 14:12:28 +11:00
parent c7bc04efc1
commit bc75ceb9e2
6 changed files with 69 additions and 35 deletions

8
Cargo.lock generated
View file

@ -670,6 +670,13 @@ dependencies = [
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "shared-failure"
version = "0.1.0"
dependencies = [
"failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "shiny-robots" name = "shiny-robots"
version = "0.1.0" version = "0.1.0"
@ -690,6 +697,7 @@ dependencies = [
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"shared-failure 0.1.0",
"slog 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "slog 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"slog-json 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "slog-json 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -28,5 +28,9 @@ toml = "0.4.5"
version = "0.2.0" version = "0.2.0"
path = "libs/badge" path = "libs/badge"
[dependencies.shared-failure]
version = "0.1.0"
path = "libs/shared-failure"
[build-dependencies] [build-dependencies]
sass-rs = "0.2.1" sass-rs = "0.2.1"

View file

@ -0,0 +1,7 @@
[package]
name = "shared-failure"
version = "0.1.0"
authors = ["Sam Rijs <srijs@airpost.net>"]
[dependencies]
failure = "0.1.1"

View file

@ -0,0 +1,37 @@
extern crate failure;
use std::fmt::{Display, Formatter, Result as FmtResult};
use std::sync::Arc;
use failure::{Backtrace, Error, Fail};
#[derive(Clone, Debug)]
pub struct SharedFailure(Arc<Error>);
impl SharedFailure {
pub fn downcast_ref<T: Fail>(&self) -> Option<&T> {
self.0.downcast_ref()
}
}
impl Fail for SharedFailure {
fn cause(&self) -> Option<&Fail> {
Some(self.0.cause())
}
fn backtrace(&self) -> Option<&Backtrace> {
Some(self.0.backtrace())
}
}
impl Display for SharedFailure {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
self.0.fmt(f)
}
}
impl From<Error> for SharedFailure {
fn from(err: Error) -> SharedFailure {
SharedFailure(Arc::new(err))
}
}

View file

@ -18,6 +18,7 @@ extern crate semver;
#[macro_use] extern crate serde_derive; #[macro_use] extern crate serde_derive;
extern crate serde; extern crate serde;
extern crate serde_json; extern crate serde_json;
extern crate shared_failure;
#[macro_use] extern crate slog; #[macro_use] extern crate slog;
extern crate slog_json; extern crate slog_json;
extern crate tokio_core; extern crate tokio_core;

View file

@ -1,13 +1,14 @@
use std::fmt::{Debug, Display, Formatter, Result as FmtResult}; use std::fmt::{Debug, Formatter, Result as FmtResult};
use std::hash::Hash; use std::hash::Hash;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use std::ops::Deref; use std::ops::Deref;
use std::sync::Mutex; use std::sync::Mutex;
use failure::{Error, Fail}; use failure::Error;
use futures::{Future, Poll}; use futures::{Future, Poll};
use futures::future::{Shared, SharedError, SharedItem}; use futures::future::{FromErr, Shared, SharedItem};
use lru_cache::LruCache; use lru_cache::LruCache;
use shared_failure::SharedFailure;
use tokio_service::Service; use tokio_service::Service;
pub struct Cache<S> pub struct Cache<S>
@ -16,7 +17,7 @@ pub struct Cache<S>
{ {
inner: S, inner: S,
duration: Duration, duration: Duration,
cache: Mutex<LruCache<S::Request, (Instant, Shared<S::Future>)>> cache: Mutex<LruCache<S::Request, (Instant, Shared<FromErr<S::Future, SharedFailure>>)>>
} }
impl<S> Debug for Cache<S> impl<S> Debug for Cache<S>
@ -50,7 +51,7 @@ impl<S> Service for Cache<S>
{ {
type Request = S::Request; type Request = S::Request;
type Response = CachedItem<S::Response>; type Response = CachedItem<S::Response>;
type Error = CachedError; type Error = SharedFailure;
type Future = Cached<S::Future>; type Future = Cached<S::Future>;
fn call(&self, req: Self::Request) -> Self::Future { fn call(&self, req: Self::Request) -> Self::Future {
@ -63,18 +64,17 @@ impl<S> Service for Cache<S>
} }
} }
} }
let shared_future = self.inner.call(req.clone()).shared(); let shared_future = self.inner.call(req.clone()).from_err().shared();
cache.insert(req, (now + self.duration, shared_future.clone())); cache.insert(req, (now + self.duration, shared_future.clone()));
Cached(shared_future) Cached(shared_future)
} }
} }
pub struct Cached<F: Future>(Shared<F>); pub struct Cached<F: Future<Error=Error>>(Shared<FromErr<F, SharedFailure>>);
impl<F> Debug for Cached<F> impl<F> Debug for Cached<F>
where F: Future + Debug, where F: Future<Error=Error> + Debug,
F::Item: Debug, F::Item: Debug
F::Error: Debug
{ {
fn fmt(&self, fmt: &mut Formatter) -> FmtResult { fn fmt(&self, fmt: &mut Formatter) -> FmtResult {
self.0.fmt(fmt) self.0.fmt(fmt)
@ -83,11 +83,11 @@ impl<F> Debug for Cached<F>
impl<F: Future<Error=Error>> Future for Cached<F> { impl<F: Future<Error=Error>> Future for Cached<F> {
type Item = CachedItem<F::Item>; type Item = CachedItem<F::Item>;
type Error = CachedError; type Error = SharedFailure;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
self.0.poll() self.0.poll()
.map_err(CachedError) .map_err(|err| (*err).clone())
.map(|async| async.map(CachedItem)) .map(|async| async.map(CachedItem))
} }
} }
@ -102,26 +102,3 @@ impl<T> Deref for CachedItem<T> {
&self.0.deref() &self.0.deref()
} }
} }
#[derive(Debug)]
pub struct CachedError(SharedError<Error>);
impl Fail for CachedError {
fn cause(&self) -> Option<&Fail> {
Some(self.0.cause())
}
fn backtrace(&self) -> Option<&::failure::Backtrace> {
Some(self.0.backtrace())
}
fn causes(&self) -> ::failure::Causes {
self.0.causes()
}
}
impl Display for CachedError {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
Display::fmt(&self.0, f)
}
}