diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 0882172..a38c4ff 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -78,12 +78,12 @@ jobs: exit 1 fi - - name: Warp example + - name: Axum example run: | - cd server-warp + cd server-axum cargo build --target wasm32-wasi --release - wasmedgec target/wasm32-wasi/release/wasmedge_warp_server.wasm wasmedge_warp_server.wasm - nohup wasmedge wasmedge_warp_server.wasm & + wasmedgec target/wasm32-wasi/release/wasmedge_axum_server.wasm wasmedge_axum_server.wasm + nohup wasmedge wasmedge_axum_server.wasm & echo $! > wasmedge.pid sleep 15 resp=$(curl http://localhost:8080/echo -X POST -d "WasmEdge") diff --git a/server-axum/.cargo/config.toml b/server-axum/.cargo/config.toml new file mode 100644 index 0000000..c20090b --- /dev/null +++ b/server-axum/.cargo/config.toml @@ -0,0 +1,3 @@ +[build] +target = "wasm32-wasi" +rustflags = ["--cfg", "wasmedge", "--cfg", "tokio_unstable"] diff --git a/server-axum/Cargo.toml b/server-axum/Cargo.toml new file mode 100644 index 0000000..c82a4b4 --- /dev/null +++ b/server-axum/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "wasmedge_axum_server" +version = "0.1.0" +edition = "2021" + +[patch.crates-io] +tokio = { git = "https://github.com/second-state/wasi_tokio.git", branch = "v1.36.x" } +socket2 = { git = "https://github.com/second-state/socket2.git", branch = "v0.5.x" } +hyper = { git = "https://github.com/second-state/wasi_hyper.git", branch = "v0.14.x" } + +[dependencies] +axum = "0.6" +bytes = "1" +futures-util = "0.3.30" +tokio = { version = "1", features = ["rt", "macros", "net", "time", "io-util"]} diff --git a/server-warp/README.md b/server-axum/README.md similarity index 100% rename from server-warp/README.md rename to server-axum/README.md diff --git a/server-axum/src/main.rs b/server-axum/src/main.rs new file mode 100644 index 0000000..c25eb85 --- /dev/null +++ b/server-axum/src/main.rs @@ -0,0 +1,35 @@ +use bytes::Bytes; +use futures_util::StreamExt; + +use axum::{extract::BodyStream, routing::get, routing::post, Router}; +use tokio::net::TcpListener; + +#[tokio::main(flavor = "current_thread")] +async fn main() { + // build our application with a route + let app = Router::new() + .route("/", get(help)) + .route("/echo", post(echo)); + + // run it + let addr = "0.0.0.0:8080"; + let tcp_listener = TcpListener::bind(addr).await.unwrap(); + println!("listening on {}", addr); + axum::Server::from_tcp(tcp_listener.into_std().unwrap()) + .unwrap() + .serve(app.into_make_service()) + .await + .unwrap(); +} + +async fn help() -> &'static str { + "Try POSTing data to /echo such as: `curl localhost:8080/echo -XPOST -d 'hello world'`\n" +} + +async fn echo(mut stream: BodyStream) -> Bytes { + if let Some(Ok(s)) = stream.next().await { + s + } else { + Bytes::new() + } +} diff --git a/server-tflite/.cargo/config.toml b/server-tflite/.cargo/config.toml new file mode 100644 index 0000000..c20090b --- /dev/null +++ b/server-tflite/.cargo/config.toml @@ -0,0 +1,3 @@ +[build] +target = "wasm32-wasi" +rustflags = ["--cfg", "wasmedge", "--cfg", "tokio_unstable"] diff --git a/server-tflite/Cargo.toml b/server-tflite/Cargo.toml index 1ef1994..e3a509c 100644 --- a/server-tflite/Cargo.toml +++ b/server-tflite/Cargo.toml @@ -3,9 +3,14 @@ name = "wasmedge_hyper_server_tflite" version = "0.1.0" edition = "2021" +[patch.crates-io] +tokio = { git = "https://github.com/second-state/wasi_tokio.git", branch = "v1.36.x" } +socket2 = { git = "https://github.com/second-state/socket2.git", branch = "v0.5.x" } +hyper = { git = "https://github.com/second-state/wasi_hyper.git", branch = "v0.14.x" } + [dependencies] -hyper_wasi = { version = "0.15", features = ["full"]} -tokio_wasi = { version = "1", features = ["rt", "macros", "net", "time", "io-util"]} +hyper = { version = "0.14", features = ["full"]} +tokio = { version = "1", features = ["rt", "macros", "net", "time", "io-util"]} image = { version = "0.23.14", default-features = false, features = ["gif", "jpeg", "ico", "png", "tiff", "webp", "bmp"] } wasi-nn = "0.4.0" anyhow = "1.0" diff --git a/server-tflite/src/main.rs b/server-tflite/src/main.rs index 44d2355..050c551 100644 --- a/server-tflite/src/main.rs +++ b/server-tflite/src/main.rs @@ -1,19 +1,22 @@ use hyper::service::{make_service_fn, service_fn}; -use hyper::{Body, Method, Request, Response, StatusCode, Server}; +use hyper::{Body, Method, Request, Response, Server, StatusCode}; +use image::io::Reader; +use image::DynamicImage; use std::convert::Infallible; +use std::io::Cursor; use std::net::SocketAddr; use std::result::Result; -use std::io::Cursor; -use image::io::Reader; -use image::DynamicImage; -use wasi_nn::{GraphBuilder, GraphEncoding, ExecutionTarget, TensorType}; +use tokio::net::TcpListener; +use wasi_nn::{ExecutionTarget, GraphBuilder, GraphEncoding, TensorType}; /// This is our service handler. It receives a Request, routes on its /// path, and returns a Future of a Response. async fn classify(req: Request) -> Result, anyhow::Error> { - let model_data: &[u8] = include_bytes!("models/mobilenet_v1_1.0_224/mobilenet_v1_1.0_224_quant.tflite"); + let model_data: &[u8] = + include_bytes!("models/mobilenet_v1_1.0_224/mobilenet_v1_1.0_224_quant.tflite"); let labels = include_str!("models/mobilenet_v1_1.0_224/labels_mobilenet_quant_v1_224.txt"); - let graph = GraphBuilder::new(GraphEncoding::TensorflowLite, ExecutionTarget::CPU).build_from_bytes(&[model_data])?; + let graph = GraphBuilder::new(GraphEncoding::TensorflowLite, ExecutionTarget::CPU) + .build_from_bytes(&[model_data])?; let mut ctx = graph.init_execution_context()?; /* let graph = unsafe { @@ -94,14 +97,14 @@ async fn classify(req: Request) -> Result, anyhow::Error> { #[tokio::main(flavor = "current_thread")] async fn main() -> Result<(), Box> { let addr = SocketAddr::from(([0, 0, 0, 0], 8080)); - let make_svc = make_service_fn(|_| { - async move { - Ok::<_, Infallible>(service_fn(move |req| { - classify(req) - })) - } - }); - let server = Server::bind(&addr).serve(make_svc); + + let listener = TcpListener::bind(addr).await?; + + let make_svc = + make_service_fn( + |_| async move { Ok::<_, Infallible>(service_fn(move |req| classify(req))) }, + ); + let server = Server::from_tcp(listener.into_std()?)?.serve(make_svc); if let Err(e) = server.await { eprintln!("server error: {}", e); } diff --git a/server-warp/Cargo.toml b/server-warp/Cargo.toml deleted file mode 100644 index 348dfbd..0000000 --- a/server-warp/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "wasmedge_warp_server" -version = "0.1.0" -edition = "2021" - -[dependencies] -bytes = "1" -tokio_wasi = { version = "1", features = ["rt", "macros", "net", "time", "io-util"]} -warp_wasi = "0.3" diff --git a/server-warp/src/main.rs b/server-warp/src/main.rs deleted file mode 100644 index 4e3ba11..0000000 --- a/server-warp/src/main.rs +++ /dev/null @@ -1,20 +0,0 @@ -use warp::Filter; - -#[tokio::main(flavor = "current_thread")] -async fn main() { - // GET / - let help = warp::get() - .and(warp::path::end()) - .map(|| "Try POSTing data to /echo such as: `curl localhost:8080/echo -XPOST -d 'hello world'`\n"); - - // POST /echo - let echo = warp::post() - .and(warp::path("echo")) - .and(warp::body::bytes()) - .map(|body_bytes: bytes::Bytes| { - format!("{}\n", std::str::from_utf8(body_bytes.as_ref()).unwrap()) - }); - - let routes = help.or(echo); - warp::serve(routes).run(([0, 0, 0, 0], 8080)).await -}