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

feat: WASM client via web-sys transport #648

Merged
merged 41 commits into from
Apr 20, 2022
Merged

feat: WASM client via web-sys transport #648

merged 41 commits into from
Apr 20, 2022

Conversation

niklasad1
Copy link
Member

@niklasad1 niklasad1 commented Jan 12, 2022

This PR adds web-sys transport to the jsonrpsee client in the browser (via WebSocket), it actually uses "std" currently but I'm not sure whether this will be an issue or not for users.

I added another feature flag async-wasm-client to core to use a client to that spawns a background task using wasm_bindgen_futures::spawn_local instead of tokio similar to how async-client works. We can probably bikeshed on the naming there.

Another option is to go by `target.'cfg(target_arch = wasm32 )' instead to reduce the number of complicated feature flags to understand in this repo...

Closing #606

let (err_tx, err_rx) = oneshot::channel();
let max_notifs_per_subscription = self.max_notifs_per_subscription;

wasm_bindgen_futures::spawn_local(async move {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://crates.io/crates/wasm-futures-executor is a candidate but doesn't compile for stable rust yet....

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we could call the WASM client "experimental" and require nightly until the wasm-futures-executor stabilizes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems be fast enough for now, let's open a issue and investigate the performance gain for it instead....


/// Sender.
#[derive(Debug)]
pub struct Sender(mpsc::UnboundedSender<WebSocketMessage>);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rustwasm/wasm-bindgen#955

The JsValue is !Send and I had to use another channel here instead of having WebSocket here directly.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah maybe this answers my question about not impling Send on the wasm Transport traits!

@niklasad1 niklasad1 marked this pull request as ready for review February 10, 2022 12:13
@niklasad1 niklasad1 requested review from a team as code owners February 10, 2022 12:13
@niklasad1 niklasad1 changed the title [WIP]: WASM client feat: WASM client via web-sys transport Feb 10, 2022
_ = timeout => Ok(Err(Error::RequestTimeout))
timeout: std::time::Duration,
rx: futures_channel::oneshot::Receiver<Result<T, Error>>,
) -> Result<Result<T, Error>, futures_channel::oneshot::Canceled> {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed to future::select to make it work for wasm

@jsdw
Copy link
Collaborator

jsdw commented Feb 24, 2022

Another option is to go by `target.'cfg(target_arch = wasm32 )' instead to reduce the number of complicated feature flags to understand in this repo...

I wonder whether it's better to have a feature flag like "js"; just because it's compiled to wasm doesn't mean it'll be executed in a browser with access to the web-sys JS APIs (and I think some other crates use "js" but I'd have to go looking to check!) :)

@athei
Copy link
Member

athei commented Feb 28, 2022

I wonder whether it's better to have a feature flag like "js"; just because it's compiled to wasm doesn't mean it'll be executed in a browser with access to the web-sys JS APIs

Does this have pluggable transpart (as in replaceable by a user)? If yes it makes sense to have a feature. If not: What is the point in compiling it for wasm without having access to the web APIs as there is no way to communicate?

I would propose using web as the feature flag name if there will be a feature flag.

@niklasad1
Copy link
Member Author

Does this have pluggable transpart (as in replaceable by a user)?

That's a good point it's quite complicated to configure the client: the transport needs --feature web-sys/wasm for the and then the abstract client needs --feature wasm-client to spawn the event loop with wasm_bindgen_futures::spawn_local.

We might want to provide a thin wrapper crate that does that mess instead of the users.

But yeah web or web-sys sounds good to me for the transport then maybe we can get rid of the feature async-client-wasm with the thin wrapper crate ☝️

"tracing",
"futures-timer",
]
async-wasm-client = [
Copy link
Member Author

@niklasad1 niklasad1 Mar 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could reduce the features if the async client was extracted to a separate crate...

then we could do some target specific assertions but won't work here.

- uses: actions/checkout@master

- name: Install
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done cargo install wasm-pack in the past; is there an advantage to doing it this way?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aah; one advantage of the script by the looks of it is that it'll download pre-compiled binaries if they exist; that's good to know!

client/transport/src/lib.rs Outdated Show resolved Hide resolved
.github/workflows/ci.yml Outdated Show resolved Hide resolved
core/src/client/mod.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@jsdw jsdw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks fantastic!

@niklasad1 niklasad1 merged commit 20e6e5d into master Apr 20, 2022
@niklasad1 niklasad1 deleted the wasm-client branch April 20, 2022 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants