diff --git a/examples/example-deno-runtime/tests.ts b/examples/example-deno-runtime/tests.ts index 0d58f13..4cd69c6 100644 --- a/examples/example-deno-runtime/tests.ts +++ b/examples/example-deno-runtime/tests.ts @@ -73,7 +73,7 @@ const imports: Imports = { }, importGenerics: ( - arg: StructWithGenerics + arg: StructWithGenerics, ): StructWithGenerics => { assertEquals(arg, { list: [0, 64], @@ -204,7 +204,7 @@ const imports: Imports = { }, importSerdeAdjacentlyTagged: ( - arg: SerdeAdjacentlyTagged + arg: SerdeAdjacentlyTagged, ): SerdeAdjacentlyTagged => { assertEquals(arg, { type: "Bar", payload: "Hello, plugin!" }); return { type: "Baz", payload: { a: -8, b: 64 } }; @@ -226,7 +226,7 @@ const imports: Imports = { }, importSerdeInternallyTagged: ( - arg: SerdeInternallyTagged + arg: SerdeInternallyTagged, ): SerdeInternallyTagged => { assertEquals(arg, { type: "Foo" }); return { type: "Baz", a: -8, b: 64 }; @@ -363,7 +363,7 @@ async function loadExamplePlugin() { if (!examplePlugin) { examplePlugin = await loadPlugin( "../example-plugin/target/wasm32-unknown-unknown/debug/example_plugin.wasm", - imports + imports, ); const { init } = examplePlugin; @@ -424,7 +424,7 @@ Deno.test("timestamp", async () => { assertEquals( plugin.exportTimestamp?.("2022-04-12T19:10:00Z"), - "2022-04-13T12:37:00Z" + "2022-04-13T12:37:00Z", ); }); @@ -441,7 +441,7 @@ Deno.test("flattened structs", async () => { fooBar: "fooBar", QUX_BAZ: -64.0, rawStruct: 32, - } + }, ); assertEquals(plugin.exportFpEnum?.("foo_bar"), { @@ -461,7 +461,7 @@ Deno.test("flattened structs", async () => { fooBar: "fooBar", QUX_BAZ: -64.0, rawStruct: 32, - } + }, ); assertEquals(plugin.exportSerdeEnum?.("foo_bar"), { @@ -495,7 +495,7 @@ Deno.test("generics", async () => { twee: [{ value: 2.0 }], }, optional_timestamp: "1970-01-01T00:00:00Z", - } + }, ); }); @@ -524,7 +524,7 @@ Deno.test("tagged enums", async () => { { type: "Baz", payload: { a: -8, b: 64 }, - } + }, ); assertEquals(plugin.exportFpInternallyTagged?.({ type: "Foo" }), { @@ -543,7 +543,7 @@ Deno.test("tagged enums", async () => { { type: "Baz", payload: { a: -8, b: 64 }, - } + }, ); assertEquals(plugin.exportSerdeInternallyTagged?.({ type: "Foo" }), { @@ -598,13 +598,13 @@ Deno.test("async struct", async () => { QUX_BAZ: 64.0, rawStruct: -32, }, - 64n + 64n, ), { fooBar: "fooBar", QUX_BAZ: -64.0, rawStruct: 32, - } + }, ); }); @@ -618,6 +618,14 @@ Deno.test("fetch async data", async () => { }); }); +Deno.test("invoke parallel requests", async () => { + const { makeParallelRequests } = await loadExamplePlugin(); + assert(makeParallelRequests); + + const data = await makeParallelRequests(); + assertEquals(data, JSON.stringify({ status: "confirmed" })); +}); + Deno.test("bytes", async () => { const { exportGetBytes, exportGetSerdeBytes } = await loadExamplePlugin(); assert(exportGetBytes); diff --git a/examples/example-plugin/Cargo.toml b/examples/example-plugin/Cargo.toml index 97005bf..fda87fa 100644 --- a/examples/example-plugin/Cargo.toml +++ b/examples/example-plugin/Cargo.toml @@ -10,10 +10,11 @@ crate-type = ["cdylib"] [dependencies] bytes = "1" -example-bindings = {path = "../example-protocol/bindings/rust-plugin"} -http = {version = "0.2"} -once_cell = {version = "1"} -redux-example = {path = "../redux-example"} -serde_bytes = {version = "0.11"} -time = {version = "0.3", features = ["serde-human-readable"]} +example-bindings = { path = "../example-protocol/bindings/rust-plugin" } +futures = "0.3" +http = { version = "0.2" } +once_cell = { version = "1" } +redux-example = { path = "../redux-example" } +serde_bytes = { version = "0.11" } +time = { version = "0.3", features = ["serde-human-readable"] } tracing = "0.1.37" diff --git a/examples/example-plugin/src/lib.rs b/examples/example-plugin/src/lib.rs index f8d4cff..dce9e7a 100644 --- a/examples/example-plugin/src/lib.rs +++ b/examples/example-plugin/src/lib.rs @@ -413,10 +413,7 @@ async fn fetch_data(r#type: String) -> Result { url: Uri::from_static("https://fiberplane.dev"), method: Method::POST, headers, - body: Some(ByteBuf::from(format!( - r#"{{"country":"🇳🇱","type":"{}"}}"#, - r#type - ))), + body: Some(ByteBuf::from(format!(r#"{{"country":"🇳🇱","type":"{}"}}"#, r#type))), }) .await; @@ -428,6 +425,22 @@ async fn fetch_data(r#type: String) -> Result { } } +#[fp_export_impl(example_bindings)] +async fn make_parallel_requests() -> String { + let request1 = fetch_data("sign-up".to_owned()); + let request2 = fetch_data("sign-up".to_owned()); + + match futures::future::join(request1, request2).await { + (Ok(response1), Ok(response2)) => { + assert_eq!(response1, response2); + response1 + } + (maybe_error1, maybe_error2) => { + format!("Error of these is an error: {maybe_error1:?}, {maybe_error2:?}") + } + } +} + #[fp_export_impl(example_bindings)] fn export_get_bytes() -> Result { import_get_bytes().map(|bytes| { diff --git a/examples/example-protocol/src/main.rs b/examples/example-protocol/src/main.rs index 21fbd42..35c4d98 100644 --- a/examples/example-protocol/src/main.rs +++ b/examples/example-protocol/src/main.rs @@ -256,6 +256,9 @@ fp_export! { /// Example how plugin could expose async data-fetching capabilities. async fn fetch_data(r#type: String) -> Result; + /// Example that shows how to make parallel requests from the guest module. + async fn make_parallel_requests() -> String; + /// Called on the plugin to give it a chance to initialize. fn init(); diff --git a/examples/example-rust-wasmer2-runtime/Cargo.toml b/examples/example-rust-wasmer2-runtime/Cargo.toml index 31de67d..296ad53 100644 --- a/examples/example-rust-wasmer2-runtime/Cargo.toml +++ b/examples/example-rust-wasmer2-runtime/Cargo.toml @@ -16,6 +16,7 @@ fp-bindgen-support = { path = "../../fp-bindgen-support", features = [ ] } http = "0.2" once_cell = "1" +rand = "0.8" rmp-serde = "1.0.0" serde = { version = "1.0", features = ["derive"] } serde_bytes = "0.11" @@ -24,7 +25,7 @@ time = { version = "0.3", features = [ "serde-well-known", "macros", ] } -tokio = { version = "1.9.0", features = ["rt", "macros"] } +tokio = { version = "1.9.0", features = ["rt-multi-thread", "macros", "time"] } tracing = "0.1.37" wasmer = { version = "2.3", features = ["compiler", "cranelift", "singlepass"] } wasmer-wasi = "2.3" diff --git a/examples/example-rust-wasmer2-runtime/src/spec/mod.rs b/examples/example-rust-wasmer2-runtime/src/spec/mod.rs index 7fcd9b6..b36e2bc 100644 --- a/examples/example-rust-wasmer2-runtime/src/spec/mod.rs +++ b/examples/example-rust-wasmer2-runtime/src/spec/mod.rs @@ -3,6 +3,7 @@ pub mod types; use bytes::Bytes; use serde_bytes::ByteBuf; +use tokio::time::{sleep, Duration}; use types::*; use super::GLOBAL_STATE; @@ -198,6 +199,9 @@ fn log(msg: String) { } async fn make_http_request(opts: Request) -> Result { + // Add a little randomized sleeping to see if we trigger potential race issues... + //sleep(Duration::from_millis(rand::random::().into())).await; + Ok(Response { body: ByteBuf::from(r#"{"status":"confirmed"}"#.to_string()), headers: opts.headers, diff --git a/examples/example-rust-wasmer2-runtime/src/test.rs b/examples/example-rust-wasmer2-runtime/src/test.rs index 2c23326..512c202 100644 --- a/examples/example-rust-wasmer2-runtime/src/test.rs +++ b/examples/example-rust-wasmer2-runtime/src/test.rs @@ -308,6 +308,16 @@ async fn fetch_async_data() -> Result<()> { Ok(()) } +#[tokio::test] +async fn make_parallel_requests() -> Result<()> { + let rt = new_runtime()?; + + let response = rt.make_parallel_requests().await?; + + assert_eq!(response, r#"{"status":"confirmed"}"#.to_string()); + Ok(()) +} + #[test] fn bytes() -> Result<()> { let rt = new_runtime()?;