Skip to content

Commit

Permalink
Merge pull request #3 from Zireael-N/optional_deps
Browse files Browse the repository at this point in the history
Make `rand` and `log` optional
  • Loading branch information
softprops authored May 30, 2020
2 parents f953cf4 + 8cbb6d1 commit 928e06c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 16 deletions.
8 changes: 5 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ categories = [
maintenance = { status = "actively-developed" }

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
default = ["log", "rand"]

[dependencies]
log = "0.4"
rand = "0.7"
log = { version = "0.4", optional = true }
rand = { version = "0.7", optional = true }
wasm-timer = "0.2"

[dev-dependencies]
pretty_env_logger = "0.4"
reqwest = "0.10"
tokio = { version = "0.2", features = ["rt-threaded","macros"] }
tokio = { version = "0.2", features = ["rt-threaded","macros"] }
40 changes: 27 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
//! jitter, and other common retry options. This objects may be reused
//! across operations. For more information see the [`RetryPolicy`](struct.RetryPolicy.html) docs.
//!
//! ```no_run
//! ```ignore
//! use again::RetryPolicy;
//! use std::time::Duration;
//!
Expand All @@ -48,13 +48,14 @@
//!
//! # Logging
//!
//! For visibility on when operations fail and are retired, a `log::trace` message is emitted,
//! For visibility on when operations fail and are retried, a `log::trace` message is emitted,
//! logging the `Debug` display of the error and the delay before the next attempt.
//!
//! # wasm
//!
//! `again` supports [WebAssembly](https://webassembly.org/) targets i.e. `wasm32-unknown-unknown` which should make this
//! crate a good fit for most environments
#[cfg(feature = "rand")]
use rand::{distributions::OpenClosed01, thread_rng, Rng};
use std::{cmp::min, future::Future, time::Duration};
use wasm_timer::Delay;
Expand Down Expand Up @@ -107,6 +108,7 @@ impl Backoff {
BackoffIter {
backoff: self,
current: 1,
#[cfg(feature = "rand")]
jitter: policy.jitter,
delay: policy.delay,
max_delay: policy.max_delay,
Expand All @@ -118,6 +120,7 @@ impl Backoff {
struct BackoffIter {
backoff: Backoff,
current: u32,
#[cfg(feature = "rand")]
jitter: bool,
delay: Duration,
max_delay: Option<Duration>,
Expand All @@ -144,8 +147,11 @@ impl Iterator for BackoffIter {

if let Some(factor) = factor {
if let Some(mut delay) = self.delay.checked_mul(factor) {
if self.jitter {
delay = jitter(delay);
#[cfg(feature = "rand")]
{
if self.jitter {
delay = jitter(delay);
}
}
if let Some(max_delay) = self.max_delay {
delay = min(delay, max_delay);
Expand All @@ -167,6 +173,7 @@ impl Iterator for BackoffIter {
#[derive(Clone)]
pub struct RetryPolicy {
backoff: Backoff,
#[cfg(feature = "rand")]
jitter: bool,
delay: Duration,
max_delay: Option<Duration>,
Expand All @@ -178,13 +185,15 @@ impl Default for RetryPolicy {
Self {
backoff: Backoff::default(),
delay: Duration::from_secs(1),
#[cfg(feature = "rand")]
jitter: false,
max_delay: None,
max_retries: 5,
}
}
}

#[cfg(feature = "rand")]
fn jitter(duration: Duration) -> Duration {
let jitter: f64 = thread_rng().sample(OpenClosed01);
let secs = (duration.as_secs() as f64) * jitter;
Expand All @@ -201,7 +210,7 @@ impl RetryPolicy {
/// Configures policy with an exponential
/// backoff delay.
///
/// By default, Futures will be retied 5 times.
/// By default, Futures will be retried 5 times.
///
/// These delays will increase in
/// length over time. You may wish to cap just how long
Expand All @@ -217,11 +226,11 @@ impl RetryPolicy {
/// Configures policy with a fixed
/// backoff delay.
///
/// By default, Futures will be retied 5 times.
/// By default, Futures will be retried 5 times.
///
/// These delays will increase in
/// length over time. You may wish to configure how many
/// times a Future will be retired using the [`with_max_retries`](struct.RetryPolicy.html#method.with_max_retries) fn
/// times a Future will be retried using the [`with_max_retries`](struct.RetryPolicy.html#method.with_max_retries) fn
pub fn fixed(delay: Duration) -> Self {
Self {
backoff: Backoff::Fixed,
Expand All @@ -234,6 +243,7 @@ impl RetryPolicy {
///
/// This is useful for services that have many clients which might all retry at the same time to avoid
/// the ["thundering herd" problem](https://en.wikipedia.org/wiki/Thundering_herd_problem)
#[cfg(feature = "rand")]
pub fn with_jitter(
mut self,
jitter: bool,
Expand Down Expand Up @@ -290,11 +300,14 @@ impl RetryPolicy {
Err(err) => {
if condition.is_retryable(&err) {
if let Some(delay) = backoffs.next() {
log::trace!(
"task failed with error {:?}. will try again in {:?}",
err,
delay
);
#[cfg(feature = "log")]
{
log::trace!(
"task failed with error {:?}. will try again in {:?}",
err,
delay
);
}
let _ = Delay::new(delay).await;
continue;
}
Expand Down Expand Up @@ -383,6 +396,7 @@ mod tests {
}

#[test]
#[cfg(feature = "rand")]
fn jitter_adds_variance_to_durations() {
assert!(jitter(Duration::from_secs(1)) != Duration::from_secs(1));
}
Expand Down Expand Up @@ -437,7 +451,7 @@ mod tests {
}

#[test]
fn retied_futures_are_send_when_tasks_are_send() {
fn retried_futures_are_send_when_tasks_are_send() {
fn test(_: impl Send) {}
test(RetryPolicy::default().retry(|| async { Ok::<u32, ()>(42) }))
}
Expand Down

0 comments on commit 928e06c

Please sign in to comment.