With this, it’s simple to get carried away and begin pondering massive: what if we may execute HTTP calls?
I’ll use the reqwest crate since I’m conversant in it. reqwest
depends on Tokio.
Cargo.toml
[dependencies]
reqwest = { model = "0.11", options = ["json"] }
tokio = { model = "1.28", options = ["full"] }
serde = { model = "1.0", options = ["derive"] }
We are able to now replace the code to make a request to <httpbin.org> and print the consequence:
#[tokio::main]
async fn most important() {
match get("http://httpbin.org/get").await {
Okay(response) => {
let consequence = response.json::<GetBody>().await;
match consequence {
Okay(json) => {
println!("{:#?}", json);
}
Err(err) => {
println!("{:#?}", err)
}
}
}
Err (err) => {
println!("{:#?}", err)
}
}
}
#[derive(Debug, Serialize, Deserialize)]
struct GetBody {
args: HashMap<String, String>,
headers: HashMap<String, String>,
origin: String,
url: String,
}
Compiling this code reveals WASM limitations, although:
#0 12.40 error: Solely options sync,macros,io-util,rt,time are supported on wasm. #0 12.40 --> /usr/native/cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.28.2/src/lib.rs:488:1 #0 12.40 | #0 12.40 488 | compile_error!("Solely options sync,macros,io-util,rt,time are supported on wasm."); #0 12.40 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
WASM shouldn’t be multi-threaded, whereas Tokio is by default. We are able to, nonetheless, configure Tokio to work in a single-thread atmosphere. Let’s begin by utilizing the options that we’d like: macros
for the most important
operate and rt
for the tokio runtime.
tokio = { model = "1.28", options = ["rt", "macros"] }
Now, we will restrict Tokio to the distinctive thread:
#[tokio::main(flavor = "current_thread")]
async fn most important() {}
Compiling now works. Nonetheless, I encounter points when working:
[2023-06-05 12:22:11.986] [error] instantiation failed: unknown import, Code: 0x62 [2023-06-05 12:22:11.986] [error] When linking module: "__wbindgen_placeholder__" , operate identify: "__wbindgen_object_drop_ref" [2023-06-05 12:22:11.986] [error] At AST node: import description [2023-06-05 12:22:11.986] [error] At AST node: import part [2023-06-05 12:22:11.986] [error] At AST node: module docker: Error response from daemon: Others("unknown import"): unknown.
The reqwest
crate doesn’t work with the WASI atmosphere. Till it does, there’s a fork aptly named reqwest_wasi. The tokio_wasi is the WASI-compatible crate for tokio
. Be aware that the latter’s model must catch up. Let’s exchange the crates:
[dependencies]
reqwest_wasi = { model = "0.11", options = ["json"] }
tokio_wasi = { model = "1.25", options = ["rt", "macros"] }
With the brand new crates, compilation works, in addition to execution. On the opposite aspect, the native picture works flawlessly, with slight adjustments for the Dockerfile:
#docker construct -f Dockerfile-native -t docker-native:1.2 .
FROM rust:1.70-slim-bullseye as construct
COPY Cargo.toml .
COPY Cargo.lock .
COPY src src
RUN apt-get replace && apt-get set up -y pkg-config libssl-dev (1)
RUN cargo construct --release
FROM debian:bullseye-slim (2)
COPY --from=construct /goal/launch/wasm-native native
ENTRYPOINT [ "/native" ]
1 | Set up required libraries for SSL |
2 | Change to a extra full base picture to keep away from putting in further libraries |
Right here’s the ultimate comparability:
REPOSITORY TAG IMAGE ID CREATED SIZE docker-native 1.0 0c227194910a 7 weeks in the past 7.09MB docker-native 1.1 3ae029030e83 22 hours in the past 7.1MB docker-native 1.2 4ff64cf9de46 7 hours in the past 123MB docker-wasm 1.0 1cc78a392477 23 hours in the past 2.61MB docker-wasm 1.1 41e38b68f4e4 22 hours in the past 2.63MB docker-wasm 1.2 6026f5bd789c 18 seconds in the past 5.34MB
I didn’t fiddle with the optimization of the native picture. Nonetheless, it will be arduous to beat the WASM picture, because it stands beneath 6MB!
There’s no probability to implement an Axum server, although.