From c4edb3b313cade236381d6e7f50f0ca043dc1825 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Thu, 26 Dec 2024 14:41:02 +0100 Subject: [PATCH] Remove broken `rest-grpc-multiplex` example (#3105) --- .github/workflows/CI.yml | 3 - examples/rest-grpc-multiplex/Cargo.toml | 20 --- examples/rest-grpc-multiplex/build.rs | 10 -- .../proto/helloworld.proto | 37 ------ examples/rest-grpc-multiplex/src/main.rs | 87 ------------- .../src/multiplex_service.rs | 118 ------------------ 6 files changed, 275 deletions(-) delete mode 100644 examples/rest-grpc-multiplex/Cargo.toml delete mode 100644 examples/rest-grpc-multiplex/build.rs delete mode 100644 examples/rest-grpc-multiplex/proto/helloworld.proto delete mode 100644 examples/rest-grpc-multiplex/src/main.rs delete mode 100644 examples/rest-grpc-multiplex/src/multiplex_service.rs diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index b50117bd..43929636 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -15,7 +15,6 @@ jobs: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - - uses: taiki-e/install-action@protoc - uses: dtolnay/rust-toolchain@beta with: components: clippy, rustfmt @@ -46,7 +45,6 @@ jobs: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - - uses: taiki-e/install-action@protoc - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 with: @@ -84,7 +82,6 @@ jobs: rust: [stable, beta] steps: - uses: actions/checkout@v4 - - uses: taiki-e/install-action@protoc - uses: dtolnay/rust-toolchain@master with: toolchain: ${{ matrix.rust }} diff --git a/examples/rest-grpc-multiplex/Cargo.toml b/examples/rest-grpc-multiplex/Cargo.toml deleted file mode 100644 index 69ece363..00000000 --- a/examples/rest-grpc-multiplex/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "example-rest-grpc-multiplex" -version = "0.1.0" -edition = "2021" -publish = false - -[dependencies] -axum = { path = "../../axum" } -futures = "0.3" -hyper = { version = "1.0.0", features = ["full"] } -#prost = "0.11" -#tokio = { version = "1", features = ["full"] } -#tonic = { version = "0.9" } -#tonic-reflection = "0.9" -tower = { version = "0.5.1", features = ["full"] } -#tracing = "0.1" -#tracing-subscriber = { version = "0.3", features = ["env-filter"] } - -[build-dependencies] -tonic-build = { version = "0.9", features = ["prost"] } diff --git a/examples/rest-grpc-multiplex/build.rs b/examples/rest-grpc-multiplex/build.rs deleted file mode 100644 index 3b3886e3..00000000 --- a/examples/rest-grpc-multiplex/build.rs +++ /dev/null @@ -1,10 +0,0 @@ -use std::{env, path::PathBuf}; - -fn main() { - let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); - - tonic_build::configure() - .file_descriptor_set_path(out_dir.join("helloworld_descriptor.bin")) - .compile(&["proto/helloworld.proto"], &["/proto"]) - .unwrap(); -} diff --git a/examples/rest-grpc-multiplex/proto/helloworld.proto b/examples/rest-grpc-multiplex/proto/helloworld.proto deleted file mode 100644 index d79a6a0d..00000000 --- a/examples/rest-grpc-multiplex/proto/helloworld.proto +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015 gRPC authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto3"; - -option java_multiple_files = true; -option java_package = "io.grpc.examples.helloworld"; -option java_outer_classname = "HelloWorldProto"; - -package helloworld; - -// The greeting service definition. -service Greeter { - // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} -} - -// The request message containing the user's name. -message HelloRequest { - string name = 1; -} - -// The response message containing the greetings -message HelloReply { - string message = 1; -} diff --git a/examples/rest-grpc-multiplex/src/main.rs b/examples/rest-grpc-multiplex/src/main.rs deleted file mode 100644 index 3ba0c0a3..00000000 --- a/examples/rest-grpc-multiplex/src/main.rs +++ /dev/null @@ -1,87 +0,0 @@ -//! Run with -//! -//! ```not_rust -//! cargo run -p example-rest-grpc-multiplex -//! ``` - -// TODO -fn main() { - eprint!("this example has not yet been updated to hyper 1.0"); -} - -// use self::multiplex_service::MultiplexService; -// use axum::{routing::get, Router}; -// use proto::{ -// greeter_server::{Greeter, GreeterServer}, -// HelloReply, HelloRequest, -// }; -// use std::net::SocketAddr; -// use tonic::{Response as TonicResponse, Status}; -// use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; - -// mod multiplex_service; - -// mod proto { -// tonic::include_proto!("helloworld"); - -// pub(crate) const FILE_DESCRIPTOR_SET: &[u8] = -// tonic::include_file_descriptor_set!("helloworld_descriptor"); -// } - -// #[derive(Default)] -// struct GrpcServiceImpl {} - -// #[tonic::async_trait] -// impl Greeter for GrpcServiceImpl { -// async fn say_hello( -// &self, -// request: tonic::Request, -// ) -> Result, Status> { -// tracing::info!("Got a request from {:?}", request.remote_addr()); - -// let reply = HelloReply { -// message: format!("Hello {}!", request.into_inner().name), -// }; - -// Ok(TonicResponse::new(reply)) -// } -// } - -// async fn web_root() -> &'static str { -// "Hello, World!" -// } - -// #[tokio::main] -// async fn main() { -// // initialize tracing -// tracing_subscriber::registry() -// .with( -// tracing_subscriber::EnvFilter::try_from_default_env() -// .unwrap_or_else(|_| "example_rest_grpc_multiplex=debug".into()), -// ) -// .with(tracing_subscriber::fmt::layer()) -// .init(); - -// // build the rest service -// let rest = Router::new().route("/", get(web_root)); - -// // build the grpc service -// let reflection_service = tonic_reflection::server::Builder::configure() -// .register_encoded_file_descriptor_set(proto::FILE_DESCRIPTOR_SET) -// .build() -// .unwrap(); -// let grpc = tonic::transport::Server::builder() -// .add_service(reflection_service) -// .add_service(GreeterServer::new(GrpcServiceImpl::default())) -// .into_service(); - -// // combine them into one service -// let service = MultiplexService::new(rest, grpc); - -// let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); -// tracing::debug!("listening on {}", addr); -// hyper::Server::bind(&addr) -// .serve(tower::make::Shared::new(service)) -// .await -// .unwrap(); -// } diff --git a/examples/rest-grpc-multiplex/src/multiplex_service.rs b/examples/rest-grpc-multiplex/src/multiplex_service.rs deleted file mode 100644 index 51550ec5..00000000 --- a/examples/rest-grpc-multiplex/src/multiplex_service.rs +++ /dev/null @@ -1,118 +0,0 @@ -use axum::{ - body::Body, - extract::Request, - http::header::CONTENT_TYPE, - response::{IntoResponse, Response}, -}; -use futures::{future::BoxFuture, ready}; -use std::{ - convert::Infallible, - task::{Context, Poll}, -}; -use tower::Service; - -pub struct MultiplexService { - rest: A, - rest_ready: bool, - grpc: B, - grpc_ready: bool, -} - -impl MultiplexService { - pub fn new(rest: A, grpc: B) -> Self { - Self { - rest, - rest_ready: false, - grpc, - grpc_ready: false, - } - } -} - -impl Clone for MultiplexService -where - A: Clone, - B: Clone, -{ - fn clone(&self) -> Self { - Self { - rest: self.rest.clone(), - grpc: self.grpc.clone(), - // the cloned services probably won't be ready - rest_ready: false, - grpc_ready: false, - } - } -} - -impl Service> for MultiplexService -where - A: Service, Error = Infallible>, - A::Response: IntoResponse, - A::Future: Send + 'static, - B: Service>, - B::Response: IntoResponse, - B::Future: Send + 'static, -{ - type Response = Response; - type Error = B::Error; - type Future = BoxFuture<'static, Result>; - - fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - // drive readiness for each inner service and record which is ready - loop { - match (self.rest_ready, self.grpc_ready) { - (true, true) => { - return Ok(()).into(); - } - (false, _) => { - ready!(self.rest.poll_ready(cx)).map_err(|err| match err {})?; - self.rest_ready = true; - } - (_, false) => { - ready!(self.grpc.poll_ready(cx))?; - self.grpc_ready = true; - } - } - } - } - - fn call(&mut self, req: Request) -> Self::Future { - // require users to call `poll_ready` first, if they don't we're allowed to panic - // as per the `tower::Service` contract - assert!( - self.grpc_ready, - "grpc service not ready. Did you forget to call `poll_ready`?" - ); - assert!( - self.rest_ready, - "rest service not ready. Did you forget to call `poll_ready`?" - ); - - // if we get a grpc request call the grpc service, otherwise call the rest service - // when calling a service it becomes not-ready so we have drive readiness again - if is_grpc_request(&req) { - self.grpc_ready = false; - let future = self.grpc.call(req); - Box::pin(async move { - let res = future.await?; - Ok(res.into_response()) - }) - } else { - self.rest_ready = false; - let future = self.rest.call(req); - Box::pin(async move { - let res = future.await.map_err(|err| match err {})?; - Ok(res.into_response()) - }) - } - } -} - -fn is_grpc_request(req: &Request) -> bool { - req.headers() - .get(CONTENT_TYPE) - .map(|content_type| content_type.as_bytes()) - .filter(|content_type| content_type.starts_with(b"application/grpc")) - .is_some() -}