From eb5708173f55d257e5ed1e6e520924e326946f1e Mon Sep 17 00:00:00 2001 From: Caio Date: Fri, 5 Jun 2026 21:34:21 -0300 Subject: [PATCH] [Rust] Add WTX - gRPC --- frameworks/wtx-grpc/Cargo.lock | 235 ++++++++++++++++++++++ frameworks/wtx-grpc/Cargo.toml | 18 ++ frameworks/wtx-grpc/Dockerfile | 13 ++ frameworks/wtx-grpc/build.rs | 26 +++ frameworks/wtx-grpc/meta.json | 12 ++ frameworks/wtx-grpc/proto/benchmark.proto | 15 ++ frameworks/wtx-grpc/src/grpc_bindings.rs | 1 + frameworks/wtx-grpc/src/main.rs | 57 ++++++ 8 files changed, 377 insertions(+) create mode 100644 frameworks/wtx-grpc/Cargo.lock create mode 100644 frameworks/wtx-grpc/Cargo.toml create mode 100644 frameworks/wtx-grpc/Dockerfile create mode 100644 frameworks/wtx-grpc/build.rs create mode 100644 frameworks/wtx-grpc/meta.json create mode 100644 frameworks/wtx-grpc/proto/benchmark.proto create mode 100644 frameworks/wtx-grpc/src/grpc_bindings.rs create mode 100644 frameworks/wtx-grpc/src/main.rs diff --git a/frameworks/wtx-grpc/Cargo.lock b/frameworks/wtx-grpc/Cargo.lock new file mode 100644 index 000000000..14a9202b2 --- /dev/null +++ b/frameworks/wtx-grpc/Cargo.lock @@ -0,0 +1,235 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "foldhash", +] + +[[package]] +name = "httparena-wtx-grpc" +version = "0.1.0" +dependencies = [ + "pb-rs", + "quick-protobuf", + "tokio", + "wtx", +] + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "log" +version = "0.4.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" + +[[package]] +name = "memchr" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "mio" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "pb-rs" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "354a34df9c65b596152598001c0fe3393379ec2db03ae30b9985659422e2607e" +dependencies = [ + "log", + "nom", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quick-protobuf" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" +dependencies = [ + "byteorder", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "socket2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tokio" +version = "1.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "wtx" +version = "0.47.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c279248c9635d9b0fdc17ee6674c1de0e3004a6853eec9f428ef0b4c2d2080e" +dependencies = [ + "foldhash", + "hashbrown", + "memchr", + "quick-protobuf", + "simdutf8", + "socket2", + "tokio", + "wtx-macros", +] + +[[package]] +name = "wtx-macros" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5c1e7897187f23097a7d1aadf7a76b834051471e8ce6d226513943c137c3acb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/frameworks/wtx-grpc/Cargo.toml b/frameworks/wtx-grpc/Cargo.toml new file mode 100644 index 000000000..2c3f50b41 --- /dev/null +++ b/frameworks/wtx-grpc/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "httparena-wtx-grpc" +version = "0.1.0" +edition = "2024" + +[build-dependencies] +pb-rs = { default-features = false, version = "0.10" } + +[dependencies] +quick-protobuf = { default-features = false, version = "0.8" } +tokio = { default-features = false, features = ["macros", "rt-multi-thread"], version = "1.0" } +wtx = { default-features = false, features = ["grpc-server", "http-server-framework", "optimizations", "optioned-server", "quick-protobuf", "tokio"], version = "0.47" } + +[profile.release] +codegen-units = 1 +lto = "thin" +opt-level = 3 +panic = "abort" diff --git a/frameworks/wtx-grpc/Dockerfile b/frameworks/wtx-grpc/Dockerfile new file mode 100644 index 000000000..14dde7620 --- /dev/null +++ b/frameworks/wtx-grpc/Dockerfile @@ -0,0 +1,13 @@ +FROM rust:1.95 AS build +RUN rustup default nightly-2026-05-07 +WORKDIR /app +COPY Cargo.toml build.rs ./ +COPY proto ./proto +RUN mkdir src && echo "fn main() {}" > src/main.rs && cargo build --release && rm -rf src/ target/release/httparena-wtx-grpc* target/release/deps/httparena_wtx-grpc* +COPY src ./src +RUN RUSTFLAGS="-C target-cpu=native" cargo build --release + +FROM debian:bookworm-slim +COPY --from=build /app/target/release/httparena-wtx-grpc /server +EXPOSE 8080 +CMD ["/server"] diff --git a/frameworks/wtx-grpc/build.rs b/frameworks/wtx-grpc/build.rs new file mode 100644 index 000000000..fcfbdcb93 --- /dev/null +++ b/frameworks/wtx-grpc/build.rs @@ -0,0 +1,26 @@ +use pb_rs::{ConfigBuilder, types::FileDescriptor}; +use std::{ + fs::{DirBuilder, remove_dir_all}, + path::Path, +}; + +fn main() { + let cmd = std::env::var("CARGO_MANIFEST_DIR").unwrap(); + let in_dir = Path::new(&cmd).join("proto"); + let out_dir = Path::new(&std::env::var("OUT_DIR").unwrap()).join("proto"); + if out_dir.exists() { + remove_dir_all(&out_dir).unwrap(); + } + DirBuilder::new().create(&out_dir).unwrap(); + FileDescriptor::run( + &ConfigBuilder::new( + &[Path::new(&cmd).join("proto/benchmark.proto").as_path()], + None, + Some(&out_dir.as_path()), + &[in_dir.as_path()], + ) + .unwrap() + .build(), + ) + .unwrap(); +} diff --git a/frameworks/wtx-grpc/meta.json b/frameworks/wtx-grpc/meta.json new file mode 100644 index 000000000..4bdacd42a --- /dev/null +++ b/frameworks/wtx-grpc/meta.json @@ -0,0 +1,12 @@ +{ + "display_name": "wtx", + "language": "Rust", + "type": "production", + "engine": "wtx", + "description": "WTX - gRPC Server", + "repo": "https://github.com/c410-f3r/wtx", + "enabled": true, + "tests": [ + "unary-grpc" + ] +} diff --git a/frameworks/wtx-grpc/proto/benchmark.proto b/frameworks/wtx-grpc/proto/benchmark.proto new file mode 100644 index 000000000..68793a2eb --- /dev/null +++ b/frameworks/wtx-grpc/proto/benchmark.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package benchmark; + +service BenchmarkService { + rpc GetSum (SumRequest) returns (SumReply); +} + +message SumRequest { + int32 a = 1; + int32 b = 2; +} + +message SumReply { + int32 result = 1; +} \ No newline at end of file diff --git a/frameworks/wtx-grpc/src/grpc_bindings.rs b/frameworks/wtx-grpc/src/grpc_bindings.rs new file mode 100644 index 000000000..a4564821a --- /dev/null +++ b/frameworks/wtx-grpc/src/grpc_bindings.rs @@ -0,0 +1 @@ +include!(concat!(env!("OUT_DIR"), "/proto/mod.rs")); diff --git a/frameworks/wtx-grpc/src/main.rs b/frameworks/wtx-grpc/src/main.rs new file mode 100644 index 000000000..bba8073f0 --- /dev/null +++ b/frameworks/wtx-grpc/src/main.rs @@ -0,0 +1,57 @@ +pub mod grpc_bindings; + +use wtx::{ + codec::format::QuickProtobuf, + collection::Vector, + grpc::{GrpcManager, GrpcMiddleware}, + http::{ + HttpRecvParams, MsgBufferString, + server_framework::{Router, ServerFrameworkBuilder, State, post}, + }, +}; + +fn main() { + let threads = std::thread::available_parallelism().map(|el| el.get()).unwrap_or(1); + let mut handlers = Vector::new(); + for _ in 0..threads { + let handle = std::thread::spawn(|| { + tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap().block_on(serve()) + }); + handlers.push(handle).unwrap(); + } + for handle in handlers { + handle.join().unwrap(); + } +} + +async fn endpoint_grpc_unary( + state: State<'_, (), GrpcManager, MsgBufferString>, +) -> wtx::Result<()> { + let sr: grpc_bindings::benchmark::SumRequest = + state.stream_aux.des_from_req_bytes(&mut state.req.msg_data.body.as_slice())?; + state.req.clear(); + let result = sr.a.wrapping_add(sr.b); + state.stream_aux.ser_to_res_bytes( + &mut state.req.msg_data.body, + grpc_bindings::benchmark::SumReply { result }, + )?; + Ok(()) +} + +async fn serve() { + let router = Router::new( + wtx::paths!(("/benchmark.BenchmarkService/GetSum", post(endpoint_grpc_unary))), + GrpcMiddleware, + ) + .unwrap(); + let _rslt = ServerFrameworkBuilder::new(HttpRecvParams::with_permissive_params(), router) + .with_stream_aux(|_| Ok(QuickProtobuf)) + .tokio( + "0.0.0.0:8080", + |_error| {}, + |_| Ok(()), + |_stream| Ok(()), + |_error| {}, + ) + .await; +}