Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace wasm-timer with custom implementation #17

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,39 @@ repository = "https://github.com/softprops/again"
keywords = ["retry", "futures", "futures-retry"]
license = "MIT"
readme = "README.md"
categories = [
"asynchronous",
"wasm",
"web-programming"
]
categories = ["asynchronous", "wasm", "web-programming"]

[lib]
crate-type = ["cdylib", "rlib"]

[badges]
maintenance = { status = "actively-developed" }

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

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

[target.'cfg(target_arch = "wasm32")'.dependencies]
web-sys = "0.3.69"
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4.42"
getrandom = { version = "0.2", features = ["js"] }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
async-std = "1.12.0"

[dev-dependencies]
approx = "0.5"
pretty_env_logger = "0.4"
reqwest = "0.11"
tokio = { version = "1", features = ["rt-multi-thread","macros"] }

[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test = "0.3"
12 changes: 8 additions & 4 deletions examples/count.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use std::{
rc::Rc,
sync::atomic::{AtomicUsize, Ordering},
};
#[cfg(target_arch = "wasm32")]
fn main() {}

#[cfg(not(target_arch = "wasm32"))]
#[tokio::main]
async fn main() -> Result<(), &'static str> {
use std::{
rc::Rc,
sync::atomic::{AtomicUsize, Ordering},
};

pretty_env_logger::init();
let counter = Rc::new(AtomicUsize::new(0));
again::retry(move || {
Expand Down
6 changes: 4 additions & 2 deletions examples/fail.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use std::error::Error;
#[cfg(target_arch = "wasm32")]
fn main() {}

#[cfg(not(target_arch = "wasm32"))]
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
async fn main() -> Result<(), Box<dyn std::error::Error>> {
pretty_env_logger::init();
again::retry(|| reqwest::get("nope")).await?;
Ok(())
Expand Down
62 changes: 62 additions & 0 deletions src/delay.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#[cfg(target_arch = "wasm32")]
enum Global {
Window(web_sys::Window),
WorkerGlobalScope(web_sys::WorkerGlobalScope),
}

#[cfg(target_arch = "wasm32")]
fn global() -> Global {
use web_sys::wasm_bindgen::JsCast;
if let Ok(s) = web_sys::js_sys::global().dyn_into::<web_sys::Window>() {
return Global::Window(s);
}
if let Ok(s) = web_sys::js_sys::global().dyn_into::<web_sys::WorkerGlobalScope>() {
return Global::WorkerGlobalScope(s);
}
panic!("no global object!")
}

#[cfg(target_arch = "wasm32")]
impl Global {
pub fn set_timeout_with_callback_and_timeout_and_arguments_0(
&self,
handler: &web_sys::js_sys::Function,
timeout: i32,
) -> Result<i32, web_sys::wasm_bindgen::JsValue> {
match self {
Self::Window(s) => {
s.set_timeout_with_callback_and_timeout_and_arguments_0(handler, timeout)
}
Self::WorkerGlobalScope(s) => {
s.set_timeout_with_callback_and_timeout_and_arguments_0(handler, timeout)
}
}
}
}

#[cfg(target_arch = "wasm32")]
pub async fn sleep(duration: std::time::Duration) -> () {
use std::convert::TryInto;
let millis = duration.as_millis().try_into().unwrap_or(i32::MAX);

let promise = web_sys::js_sys::Promise::new(&mut |resolve, _| {
global()
.set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, millis)
.unwrap();
});
let js_fut = wasm_bindgen_futures::JsFuture::from(promise);
let _ = js_fut.await;
}

#[cfg(not(target_arch = "wasm32"))]
pub async fn sleep(duration: std::time::Duration) -> () {
async_std::task::sleep(duration).await;
}

pub struct Delay;

impl Delay {
pub async fn new(duration: std::time::Duration) -> () {
sleep(duration).await;
}
}
7 changes: 6 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@
#[cfg(feature = "rand")]
use rand::{distributions::OpenClosed01, thread_rng, Rng};
use std::{cmp::min, future::Future, time::Duration};
use wasm_timer::Delay;

pub mod delay;

use delay::Delay;

/// Retries a fallible `Future` with a default `RetryPolicy`
///
Expand Down Expand Up @@ -634,6 +637,7 @@ where
}

#[cfg(test)]
#[cfg(not(target_arch = "wasm32"))]
mod tests {
use super::*;
use approx::assert_relative_eq;
Expand Down Expand Up @@ -715,6 +719,7 @@ mod tests {
test(|| async { Ok::<u32, ()>(42) });
}

#[ignore]
#[test]
fn retried_futures_are_send_when_tasks_are_send() {
fn test(_: impl Send) {}
Expand Down
12 changes: 12 additions & 0 deletions tests/wasm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![cfg(all(test, target_arch = "wasm32"))]

wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);

use again::delay::Delay;

use wasm_bindgen_test::*;

#[wasm_bindgen_test]
async fn wait_two_seconds() {
let _ = Delay::new(std::time::Duration::from_secs(2)).await;
}