Skip to content

Commit

Permalink
Worker and NodeJS Support (#7)
Browse files Browse the repository at this point in the history
* Worker and NodeJS Support

* Fixed CI errors
  • Loading branch information
whizsid committed Mar 11, 2023
1 parent ca80d5f commit c395bd6
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 37 deletions.
21 changes: 17 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ jobs:
- run: cargo check --no-default-features --features tokio-util
- run: cargo check --no-default-features --features tokio-test-util
- run: cargo check --no-default-features --features tokio
- run: cargo check --no-default-features --features serde
- run: cargo check --no-default-features

unittest:
Expand All @@ -31,19 +32,31 @@ jobs:
- run: cargo test --no-default-features --features tokio-util
- run: cargo test --no-default-features --features tokio-test-util
- run: cargo test --no-default-features --features tokio
- run: cargo test --no-default-features --features serde
- run: cargo test --no-default-features

inttest:
name: Integration Test
inttestbrowser:
name: Integration Test Browser
runs-on: ubuntu-latest
env:
RUSTFLAGS: "--cfg browser"
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- name: Install
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh

- run: wasm-pack test --headless --chrome --features tokio-test-util
- run: wasm-pack test --headless --firefox --features tokio-test-util
- run: wasm-pack test --headless --firefox --features tokio-test-util,serde
- run: wasm-pack test --headless --chrome --features tokio-test-util,serde
inttestnode:
name: Integration Test Node
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- name: Install
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- run: wasm-pack test --node --features tokio-test-util,serde
fmt:
name: Rustfmt
runs-on: ubuntu-latest
Expand Down
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,15 @@ futures = {version= "^0.3", optional = true}
parking_lot = {version= "^0.12", optional = true }
pin-utils = {version = "^0.1", optional = true }
js-sys = "^0.3"
wasm-bindgen = {version = "^0.2", optional = true }
web-sys = { version = "^0.3", features = ["Performance", "Window"] }
wasm-bindgen = "^0.2"
slab = { version = "^0.4", optional = true }
serde_crate = { package = "serde" , version = "^1.0", optional = true, default-features = false }

[features]
default = ["tokio", "tokio-util"]
tokio-test-util = ["tokio"]
tokio-util = ["slab", "tokio"]
tokio = ["futures", "parking_lot", "pin-utils", "wasm-bindgen"]
tokio = ["futures", "parking_lot", "pin-utils"]
serde = ["serde_crate"]

[dev-dependencies]
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ tasks(`Promise`) in browser scope. If we implemented such without caring
about background tasks, then this implementation will not match with the
tokio's original implementation.

## Todo
## Features

- Serde Support (Support de/serializing by introducing a new feature
`serde`)
- Serde Support (`serde` feature flag)
- Worker and NodeJS Support
- Test Utilities
39 changes: 39 additions & 0 deletions src/js.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use js_sys::Object;
use wasm_bindgen::{prelude::wasm_bindgen, JsCast};

#[wasm_bindgen]
extern "C" {
pub type GlobalScope;

pub type Performance;

#[wasm_bindgen(structural, method, getter, js_name = "performance")]
pub fn performance(this: &GlobalScope) -> Performance;

#[wasm_bindgen(method, js_name = "now")]
pub fn now(this: &Performance) -> f64;

#[cfg(feature = "tokio")]
#[wasm_bindgen(catch , method, js_name = setTimeout)]
pub fn set_timeout_with_callback_and_timeout_and_arguments_0(
this: &GlobalScope,
handler: &::js_sys::Function,
timeout: i32,
) -> Result<i32, wasm_bindgen::JsValue>;
}

pub fn performance_now() -> f64 {
let global_this: Object = js_sys::global();
let global_scope = global_this.unchecked_ref::<GlobalScope>();
global_scope.performance().now()
}

#[cfg(feature = "tokio")]
pub fn set_timeout(
handler: &::js_sys::Function,
timeout: i32,
) -> Result<i32, wasm_bindgen::JsValue> {
let global_this: Object = js_sys::global();
let global_scope = global_this.unchecked_ref::<GlobalScope>();
global_scope.set_timeout_with_callback_and_timeout_and_arguments_0(handler, timeout)
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
mod js;
pub mod std;
#[cfg(feature = "tokio")]
pub(crate) mod timer;
Expand Down
8 changes: 3 additions & 5 deletions src/std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use std::ops::{Add, AddAssign, Sub, SubAssign};
use std::time::Duration;

use crate::js::performance_now;

#[derive(Debug, Copy, Clone)]
pub struct Instant {
/// Unit is milliseconds.
Expand Down Expand Up @@ -63,11 +65,7 @@ impl Instant {
}

pub(crate) fn now_js() -> Instant {
let val = web_sys::window()
.expect("not in a browser")
.performance()
.expect("performance object not available")
.now();
let val = performance_now();
Instant { inner: val }
}

Expand Down
25 changes: 11 additions & 14 deletions src/timer/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::task::Context;
use std::time::Duration;
use wasm_bindgen::{closure::Closure, JsCast};

use crate::js::set_timeout;
use crate::std::Instant;
use crate::timer::{Timer, TimerHandle};

Expand Down Expand Up @@ -69,23 +70,19 @@ fn schedule_callback(timer: Arc<Mutex<Timer>>, when: Duration) {
if super::clock::clock().paused() {
cb();
} else {
let _ = web_sys::window()
.expect("Unable to access Window")
.set_timeout_with_callback_and_timeout_and_arguments_0(
Closure::once_into_js(cb).unchecked_ref(),
i32::try_from(when.as_millis()).unwrap_or(0),
)
.unwrap();
}

#[cfg(not(feature = "tokio-test-util"))]
let _ = web_sys::window()
.expect("Unable to access Window")
.set_timeout_with_callback_and_timeout_and_arguments_0(
&Closure::once_into_js(cb).unchecked_ref(),
let _ = set_timeout(
Closure::once_into_js(cb).unchecked_ref(),
i32::try_from(when.as_millis()).unwrap_or(0),
)
.unwrap();
}

#[cfg(not(feature = "tokio-test-util"))]
let _ = set_timeout(
Closure::once_into_js(cb).unchecked_ref(),
i32::try_from(when.as_millis()).unwrap_or(0),
)
.unwrap();
}

struct Waker {
Expand Down
9 changes: 2 additions & 7 deletions src/tokio/interval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,14 @@ impl Interval {
}
}

#[derive(Debug, PartialEq, Clone, Copy, Eq)]
#[derive(Debug, PartialEq, Clone, Copy, Eq, Default)]
pub enum MissedTickBehavior {
#[default]
Burst,
Delay,
Skip,
}

impl Default for MissedTickBehavior {
fn default() -> Self {
MissedTickBehavior::Burst
}
}

impl MissedTickBehavior {
/// If a tick is missed, this method is called to determine when the next tick should happen.
fn next_timeout(&self, timeout: Instant, now: Instant, period: Duration) -> Instant {
Expand Down
3 changes: 2 additions & 1 deletion tests/web.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use wasm_bindgen_test::{wasm_bindgen_test, wasm_bindgen_test_configure};

#[cfg(browser)]
wasm_bindgen_test_configure!(run_in_browser);

#[cfg(feature = "serde")]
Expand All @@ -13,7 +14,7 @@ pub fn test_serde() {
}

#[cfg(feature = "tokio-test-util")]
pub mod web_tests {
pub mod tokio_tests {
use super::*;
use std::{pin::Pin, sync::Once, time::Duration};

Expand Down

0 comments on commit c395bd6

Please sign in to comment.