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

Proposal: Replace wasm-bindgen with WASI #40

Open
bcheidemann opened this issue Mar 10, 2023 · 4 comments
Open

Proposal: Replace wasm-bindgen with WASI #40

bcheidemann opened this issue Mar 10, 2023 · 4 comments
Labels
nodejs Issue relates specifically to experimental NodeJS support pr-welcome This would be a good fix/feature, but the maintainer isn't planning on doing the work

Comments

@bcheidemann
Copy link
Contributor

bcheidemann commented Mar 10, 2023

Problem statement

The current implementation of @action-validator/core and @action-validator/cli requires JS glue code for any kind of system access (e.g. network, filesystem, and even logging). This is not ideal since it means that certain crates are not (easily) usable by the WASM and for each case we need to find an alternative implementation for JS or use a different crate. This could result in an undue maintenance burden and the features supported by @action-validator/* lagging behind the native binary.

What is currently affected?

  1. glob validation
  2. "use" validation remote-checks feature

Possible solution (WASI)

WebAssembly System Interface (WASI) is a modular system interface for WASM which allows filesystem and network access directly from WASM code. Pivoting from WASM bindgen to using WASI has the following benefits:

  1. Direct system access means more crates will "just work" without the need for additional JS glue code
  2. It allows us to trivially target more platforms, since it is set to be officially supported by Node.js, Deno, and is even supported in the browser by some third party NPM modules (e.g. wasi-js).

WASI is currently well supported by RUST via the wasm32-wasi target and I have used it in a couple of smaller projects now with some success. I would suggest compiling to the wasm32-wasi target and consuming the resulting *.wasm binary using wasi-js, since this exposes the same API as is exposed by Node.js and Deno and can be easily removed in future when these APIs stabalise.

Limitations (WASI)

The main limitation is that WASI is currently at the proposal stage and is not yet an official standard. Although relying on an unofficial standard isn't ideal, WASI seems to have a lot of momentum behind it and progress seems very unlikely to stall out.


@mpalmer I'd be interested to get your opinion on this? I think it would be worthwhile to at least do a PoC for this since it would likely solve the issue of supporting the remote-checks feature and glob validation with very little extra effort and reduce future maintenance burden of WASM/NPM support.


Update (18/03/2023)

I had some difficulty trying to expose library methods to @action-validator/core using WASI. Having looked into alternatives, it may be better (for now) to pivot to building on the Node-API. The following packages are possible solutions:

  1. NAPI-RS
  2. Node Bindgen
  3. Neon

Limitations (Node-API)

The primary limitation of using the Node-API is portability. While a WASI build would (in theory) be compatible with any target which supports WASI (Node, Deno, Python, Wasmtime etc), a Node-API would only be compatible with Node.

@mpalmer
Copy link
Owner

mpalmer commented Mar 11, 2023

I don't really have the expertise to make the best decision on this, I think. WASI does seem like a better approach than trying to tiptoe around the great mass of crates that won't ever be WASM-compatible, and your suggestion of at least trying it out on a branch and seeing what explodes seems like a great first step.

@bcheidemann
Copy link
Contributor Author

I don't really have the expertise to make the best decision on this, I think. WASI does seem like a better approach than trying to tiptoe around the great mass of crates that won't ever be WASM-compatible, and your suggestion of at least trying it out on a branch and seeing what explodes seems like a great first step.

@mpalmer I think that's a good approach :) I'll do some tinkering this weekend and see how I get on

@bcheidemann
Copy link
Contributor Author

I've had some success with compiling the binary to wasm32-wasi and consuming the resulting *.wasm file from Node. It is able to log to stdout and stderr, and well as read the input file using the standard library, without any changes to the code (as are currently needed for JS support). However, I had some issues with the glob validation, which seemed to be unable to match files, and therefore always resulted in an error. Other than that issue, this seems like a promising direction for the CLI, but in order to support library usage (i.e. @action-validator/core), more investigation is needed. As I understand it, node-bindgen can be used with the wasm32-wasi compilation target and I did have some success with compiling trivial libraries, but ended up encountering a lot of nebulous build errors and haven't gotten close to being able to compile lib.rs to a usable "*.wasm" file.

Having done some more research into other options, the following may also be worth looking into:

  1. NAPI-RS
  2. Node Bindgen
  3. Neon

As far as I know, these only target Node.js, and would rule out supporting other targets such as Deno, the browser, wasmtime etc. Maybe this is an acceptable trade-off if WASI is not yet a practical solution.

@bcheidemann
Copy link
Contributor Author

Following some discussion with @award28 and @mpalmer I am now leaning towards N-API as a solution to this problem and will re-focus my efforts in this direction.

@mpalmer mpalmer added pr-welcome This would be a good fix/feature, but the maintainer isn't planning on doing the work nodejs Issue relates specifically to experimental NodeJS support labels Jan 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
nodejs Issue relates specifically to experimental NodeJS support pr-welcome This would be a good fix/feature, but the maintainer isn't planning on doing the work
Projects
None yet
Development

No branches or pull requests

2 participants