Skip to content

Commit

Permalink
Use wasm-compatible sleep if compiled for wasm32 (#92)
Browse files Browse the repository at this point in the history
  • Loading branch information
wackazong authored Aug 22, 2024
1 parent bfd131d commit 3ec2da9
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 30 deletions.
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,14 @@ jobs:
env:
RUST_LOG: DEBUG
RUST_BACKTRACE: full

wasm-unit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- run: wasm-pack test --node
env:
RUST_LOG: DEBUG
RUST_BACKTRACE: full
23 changes: 21 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,27 @@ version = "0.4.4"
fastrand = "2.0.0"
tokio = { version = "1", features = ["time"] }

[target.'cfg(target_arch = "wasm32")'.dependencies]
gloo-timers = { version = "0.3", features = ["futures"] }

[dev-dependencies]
anyhow = "1"
reqwest = "0.12"
tokio = { version = "1", features = ["time", "rt", "macros", "sync", "rt-multi-thread"] }
sqlx = { version = "0.8.0", features = ["runtime-tokio", "sqlite"] }

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
tokio = { version = "1", features = [
"macros",
"rt",
"sync",
], default-features = false }
wasm-bindgen-test = "0.3"

[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
sqlx = { version = "0.8.0", features = ["runtime-tokio", "sqlite"] }
tokio = { version = "1", features = [
"time",
"rt",
"macros",
"sync",
"rt-multi-thread",
] }
11 changes: 8 additions & 3 deletions examples/blocking.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
use anyhow::Result;
use backon::BlockingRetryable;
use backon::ExponentialBuilder;

// For more examples, please see: https://docs.rs/backon/#examples

fn fetch() -> Result<String> {
Ok("hello, world!".to_string())
}

// this example does not run on wasm32-unknown-unknown
#[cfg(not(target_arch = "wasm32"))]
fn main() -> Result<()> {
let content = fetch.retry(&ExponentialBuilder::default()).call()?;
use backon::BlockingRetryable;

let content = fetch.retry(&backon::ExponentialBuilder::default()).call()?;
println!("fetch succeeded: {}", content);

Ok(())
}

#[cfg(target_arch = "wasm32")]
fn main() {}
15 changes: 9 additions & 6 deletions examples/closure.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
use anyhow::Result;
use backon::BlockingRetryable;
use backon::ExponentialBuilder;

// For more examples, please see: https://docs.rs/backon/#examples

fn main() -> Result<()> {
// this example does not run on wasm32-unknown-unknown
#[cfg(not(target_arch = "wasm32"))]
fn main() -> anyhow::Result<()> {
use backon::BlockingRetryable;

let var = 42;
// `f` can use input variables
let f = || Ok::<u32, anyhow::Error>(var);
let result = f.retry(&ExponentialBuilder::default()).call()?;
let result = f.retry(&backon::ExponentialBuilder::default()).call()?;
println!("var = {result}");

Ok(())
}

#[cfg(target_arch = "wasm32")]
fn main() {}
18 changes: 11 additions & 7 deletions examples/sqlx.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
use anyhow::Result;
use backon::ExponentialBuilder;
use backon::Retryable;
use sqlx::sqlite::SqlitePoolOptions;
// For more examples, please see: https://docs.rs/backon/#examples

// this example does not run on wasm32-unknown-unknown
#[cfg(not(target_arch = "wasm32"))]
#[tokio::main]
async fn main() -> Result<()> {
let pool = SqlitePoolOptions::new()
async fn main() -> anyhow::Result<()> {
use backon::Retryable;

let pool = sqlx::sqlite::SqlitePoolOptions::new()
.max_connections(5)
.connect("sqlite::memory:")
.await?;

let row: (i64,) = (|| sqlx::query_as("SELECT $1").bind(150_i64).fetch_one(&pool))
.retry(&ExponentialBuilder::default())
.retry(&backon::ExponentialBuilder::default())
.await?;

assert_eq!(row.0, 150);

Ok(())
}

#[cfg(target_arch = "wasm32")]
fn main() {}
3 changes: 3 additions & 0 deletions src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ impl Iterator for ConstantBackoff {
mod tests {
use std::time::Duration;

#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;

use crate::backoff::BackoffBuilder;
use crate::constant::ConstantBuilder;

Expand Down
3 changes: 3 additions & 0 deletions src/exponential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ pub(crate) fn saturating_mul(d: Duration, rhs: f32) -> Duration {
mod tests {
use std::time::Duration;

#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;

use crate::backoff::BackoffBuilder;
use crate::exponential::ExponentialBuilder;

Expand Down
3 changes: 3 additions & 0 deletions src/fibonacci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ impl Iterator for FibonacciBackoff {
mod tests {
use std::time::Duration;

#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;

use crate::backoff::BackoffBuilder;
use crate::fibonacci::FibonacciBuilder;

Expand Down
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,14 @@ pub use retry::Retryable;
mod retry_with_context;
pub use retry_with_context::RetryableWithContext;

#[cfg(not(target_arch = "wasm32"))]
mod blocking_retry;
#[cfg(not(target_arch = "wasm32"))]
pub use blocking_retry::BlockingRetry;
#[cfg(not(target_arch = "wasm32"))]
pub use blocking_retry::BlockingRetryable;

#[cfg(not(target_arch = "wasm32"))]
mod blocking_retry_with_context;
#[cfg(not(target_arch = "wasm32"))]
pub use blocking_retry_with_context::BlockingRetryableWithContext;
24 changes: 18 additions & 6 deletions src/retry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ use std::task::Context;
use std::task::Poll;
use std::time::Duration;

#[cfg(not(target_arch = "wasm32"))]
use tokio::time::{sleep, Sleep};

#[cfg(target_arch = "wasm32")]
use gloo_timers::future::{sleep, TimeoutFuture as Sleep};

use crate::backoff::BackoffBuilder;
use crate::Backoff;

Expand Down Expand Up @@ -208,7 +214,7 @@ enum State<T, E, Fut: Future<Output = Result<T, E>>> {
Idle,
Polling(Fut),
// TODO: we need to support other sleeper
Sleeping(tokio::time::Sleep),
Sleeping(Sleep),
}

impl<B, T, E, Fut, FutureFn, RF, NF> Future for Retry<B, T, E, Fut, FutureFn, RF, NF>
Expand Down Expand Up @@ -253,7 +259,7 @@ where
None => return Poll::Ready(Err(err)),
Some(dur) => {
(this.notify)(&err, dur);
this.state = State::Sleeping(tokio::time::sleep(dur));
this.state = State::Sleeping(sleep(dur));
continue;
}
}
Expand Down Expand Up @@ -282,14 +288,20 @@ mod tests {

use tokio::sync::Mutex;

#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;

#[cfg(not(target_arch = "wasm32"))]
use tokio::test;

use super::*;
use crate::exponential::ExponentialBuilder;

async fn always_error() -> anyhow::Result<()> {
Err(anyhow::anyhow!("test_query meets error"))
}

#[tokio::test]
#[test]
async fn test_retry() -> anyhow::Result<()> {
let result = always_error
.retry(&ExponentialBuilder::default().with_min_delay(Duration::from_millis(1)))
Expand All @@ -300,7 +312,7 @@ mod tests {
Ok(())
}

#[tokio::test]
#[test]
async fn test_retry_with_not_retryable_error() -> anyhow::Result<()> {
let error_times = Mutex::new(0);

Expand All @@ -325,7 +337,7 @@ mod tests {
Ok(())
}

#[tokio::test]
#[test]
async fn test_retry_with_retryable_error() -> anyhow::Result<()> {
let error_times = Mutex::new(0);

Expand All @@ -350,7 +362,7 @@ mod tests {
Ok(())
}

#[tokio::test]
#[test]
async fn test_fn_mut_when_and_notify() -> anyhow::Result<()> {
let mut calls_retryable: Vec<()> = vec![];
let mut calls_notify: Vec<()> = vec![];
Expand Down
22 changes: 16 additions & 6 deletions src/retry_with_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ use std::task::Context;
use std::task::Poll;
use std::time::Duration;

#[cfg(not(target_arch = "wasm32"))]
use tokio::time::{sleep, Sleep};

#[cfg(target_arch = "wasm32")]
use gloo_timers::future::{sleep, TimeoutFuture as Sleep};

use crate::backoff::BackoffBuilder;
use crate::Backoff;

Expand Down Expand Up @@ -255,7 +261,7 @@ enum State<T, E, Ctx, Fut: Future<Output = (Ctx, Result<T, E>)>> {
Idle(Option<Ctx>),
Polling(Fut),
// TODO: we need to support other sleeper
Sleeping((Option<Ctx>, tokio::time::Sleep)),
Sleeping((Option<Ctx>, Sleep)),
}

impl<B, T, E, Ctx, Fut, FutureFn, RF, NF> Future for Retry<B, T, E, Ctx, Fut, FutureFn, RF, NF>
Expand Down Expand Up @@ -302,8 +308,7 @@ where
None => return Poll::Ready((ctx, Err(err))),
Some(dur) => {
(this.notify)(&err, dur);
this.state =
State::Sleeping((Some(ctx), tokio::time::sleep(dur)));
this.state = State::Sleeping((Some(ctx), sleep(dur)));
continue;
}
}
Expand Down Expand Up @@ -331,12 +336,17 @@ where
mod tests {
use std::time::Duration;

use anyhow::anyhow;
use anyhow::{anyhow, Result};
use tokio::sync::Mutex;

#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;

#[cfg(not(target_arch = "wasm32"))]
use tokio::test;

use super::*;
use crate::exponential::ExponentialBuilder;
use anyhow::Result;

struct Test;

Expand All @@ -346,7 +356,7 @@ mod tests {
}
}

#[tokio::test]
#[test]
async fn test_retry_with_not_retryable_error() -> Result<()> {
let error_times = Mutex::new(0);

Expand Down

0 comments on commit 3ec2da9

Please sign in to comment.