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: Adding a Wasm / WasmEdge target #5331

Open
juntao opened this issue Jan 2, 2023 · 7 comments
Open

Feat: Adding a Wasm / WasmEdge target #5331

juntao opened this issue Jan 2, 2023 · 7 comments
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. T-wasm Topic: Web Assembly

Comments

@juntao
Copy link

juntao commented Jan 2, 2023

Is your feature request related to a problem? Please describe.

Currently, when developers compile their tokio applications to Wasm, the applications are going to fail at runtime due to Wasm's lack of support for standard networking APIs. We would like to implement a feature flag for tokio to support the wasm32-wasi compiler target -- specifically for the WasmEdge Runtime.

Describe the solution you'd like

We would like to start an effort to merge our fork upstream to tokio's main repo.

Describe alternatives you've considered

Please see the background and our research below.

Additional context

One of the emerging use cases of WebAssembly (Wasm) is a lightweight and secure alternative to Linux containers. Leading container management tools, such as Docker, containerd, Podman / crun, and Kubernetes, have all supported Wasm containers, and in particular WasmEdge, for this reason.

However, to run containerized microservices and serverless functions in Wasm, we need advanced networking sockets in the Wasm runtime. By “advanced”, I mean non-blocking and async sockets. Ideally, we would have a Wasm compiler target in tokio so that when tokio applications are compiled for the wasm32-wasi target, it will utilize Wasm socket APIs. Yet, the official Wasm standards have been slow to incorporate sockets.

To support users and customers who wish to use tokio and Rust networking apps in Wasm today, the WasmEdge community decided to create its own libc-like socket API in Wasm. WasmEdge is the default Wasm runtime distributed with Docker Desktop and Fedora / Red Hat EPEL. It's networking sockets API can reach a wide developer audience.

We forked tokio to support the WasmEdge socket API when compiling to wasm32-wasi. The approach has gained some tractions:

Example 1: This is a popular microservice template for an HTTP service backed by a MySQL server. Both the HTTP server (using forked hyper) and MySQL client (using forked mysql_async) in the WasmEdge app are based on the tokio fork.

https://github.com/second-state/microservice-rust-mysql

Example 2: This is a port of the popular Dapr SDK to Wasm. It utilizes (a forked) request on top of the forked tokio to perform HTTP API calls.

https://github.com/second-state/dapr-sdk-wasi
https://github.com/second-state/dapr-wasm

Forking tokio is only a temporary solution to demonstrate demands for this type of application. Now we would like to merge the fork back into tokio so that downstream crates that depend on tokio could also benefit.

Specially, we would like to propose the following:

  • Add a feature flag wasmedge
  • When the feature is turned on AND the compiler target is wasm32-wasi, tokio will use WasmEdge sockets.

Please let me know your thoughts and happy new year!

@juntao juntao added A-tokio Area: The main tokio crate C-feature-request Category: A feature request. labels Jan 2, 2023
@Darksonn Darksonn added the T-wasm Topic: Web Assembly label Jan 2, 2023
@Darksonn
Copy link
Contributor

Darksonn commented Jan 2, 2023

Would you be able to elaborate on how supporting wasmedge is different from our existing support for wasm32-wasi?

@juntao
Copy link
Author

juntao commented Jan 2, 2023

Would you be able to elaborate on how supporting wasmedge is different from our existing support for wasm32-wasi?

Yes. The current tokio support for wasm sockets is based on a draft WASI spec. WasmEdge supports that spec as well. The problem is that the WASI socket draft is too crude and slow evolving. For example, it does not support non-blocking I/O. That makes it difficult to use in many applications.

We had hoped that WasmEdge's approach to sockets will eventually become a WASI standard. But that process is slow moving. That's why we forked tokio for WasmEdge users last year to demonstrate that there is a community / market need for more advanced sockets.

Cheers
Michael

@Darksonn
Copy link
Contributor

Darksonn commented Jan 2, 2023

I'm not sure I understand the point about non-blocking I/O. We already use something called poll_oneoff in mio, which sounds like a tool for non-blocking I/O to me.

Anyway, I looked over it and tried to understand the differences. Is this list correct?

  • You have a separate TcpListener type for some reason.
  • You are actually able to create new sockets from within wasm.
  • You implement a bunch of socket options that we don't already have in wasi.

@juntao
Copy link
Author

juntao commented Jan 2, 2023

Yes. Tokio MIO is doing it correctly. However, if you use the tokio MIO to write an app and compile it into Wasm -- it will compile successfully but at runtime it will fail since the Wasm runtime does not support poll_oneoff.

WasmEdge provides its own implementation of poll_oneoff in WasmEdge WASI socket 😅

@Darksonn
Copy link
Contributor

Darksonn commented Jan 2, 2023

I notice that you go through your wasmedge_wasi_socket crate to call things like poll_oneoff even though the wasi crate also provides that method. Does the one from the wasi crate not work?

To be honest, I am reluctant to go for a solution where Tokio needs to put in work to support every single wasm runtime out there separately.

@juntao
Copy link
Author

juntao commented Jan 2, 2023

Yeah. The WASI socket proposal is still an early draft and misses a lot of things -- it has been like that for a long time now. That's why we forked it.

I think what's more likely to happen now is to have the "community" adopt a solution first, and then make that solution into a standard. That is where we are ...

@juntao
Copy link
Author

juntao commented Jan 2, 2023

I'd like to clarify that poll_oneoff is in the current wasmtime and WasmEdge implementation of the WASI socket proposal. But it misses some important features such as TcpStream::connect and TcpListener::bind. See more discussion here.

#4827

Again, our hope is that WasmEdge sockets will become part of WASI sockets in the future.

Yes. Tokio MIO is doing it correctly. However, if you use the tokio MIO to write an app and compile it into Wasm -- it will compile successfully but at runtime it will fail since the Wasm runtime does not support poll_oneoff.

WasmEdge provides its own implementation of poll_oneoff in WasmEdge WASI socket 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. T-wasm Topic: Web Assembly
Projects
None yet
Development

No branches or pull requests

2 participants