Skip to content

Instantly share code, notes, and snippets.

@nwisemanII
Last active November 29, 2023 16:04
Show Gist options
  • Save nwisemanII/047e6ea42f2321133e6eb65e2b34608f to your computer and use it in GitHub Desktop.
Save nwisemanII/047e6ea42f2321133e6eb65e2b34608f to your computer and use it in GitHub Desktop.
Help With Tower + GRPC
[package]
name = "simple_ti"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[[bin]]
name = "simple_ti"
path = "src/client.rs"
[[bin]]
name = "simple_ti_server"
path = "src/server.rs"
[dependencies]
http = "1.0.0"
http-body = "1.0.0"
hyper = { version = "1.0.1", features = ["full"] }
prost = "0.12.3"
tokio = { version = "1.34.0", features = ["macros", "full"] }
tonic = "0.10.2"
tonic-build = "0.10.2"
tower = "0.4.13"
[build-dependencies]
tonic-build = "0.10.2"
error[E0277]: the trait bound `MyMiddleware<Routes>: tower::Service<tonic::codegen::http::request::Request<tonic::transport::Body>>` is not satisfied
--> src/server.rs:61:10
|
61 | .serve(addr)
| ^^^^^ the trait `tower::Service<tonic::codegen::http::request::Request<tonic::transport::Body>>` is not implemented for `MyMiddleware<Routes>`
|
= help: the trait `tower::Service<tonic::Request<T>>` is implemented for `MyMiddleware<A>`
= note: required for `tonic::service::interceptor::InterceptedService<MyMiddleware<Routes>, fn(tonic::Request<()>) -> Result<tonic::Request<()>, Status> {intercept}>` to implement `tower::Service<tonic::codegen::http::request::Request<tonic::transport::Body>>`
= note: 1 redundant requirement hidden
= note: required for `tower::timeout::Timeout<tonic::service::interceptor::InterceptedService<MyMiddleware<Routes>, fn(tonic::Request<()>) -> Result<tonic::Request<()>, Status> {intercept}>>` to implement `tower::Service<tonic::codegen::http::request::Request<tonic::transport::Body>>`
use hyper::body;
use std::time::Duration;
use tonic::transport::Server;
use tonic::{Request, Response, Status};
use hello_world::greeter_server::{Greeter, GreeterServer};
use hello_world::{HelloReply, HelloRequest};
use tower::{Layer, Service, ServiceBuilder};
// use hyper::body::Body;
use http_body::Body;
pub mod hello_world {
tonic::include_proto!("helloworld");
}
#[derive(Debug, Default)]
pub struct MyGreeter {}
#[tonic::async_trait]
impl Greeter for MyGreeter {
async fn say_hello(
&self,
request: Request<HelloRequest>,
) -> Result<Response<HelloReply>, Status> {
println!("Got a request from {:?}", request.remote_addr());
let reply = hello_world::HelloReply {
message: format!("Hello {}!", request.into_inner().name),
};
Ok(Response::new(reply))
}
}
// An interceptor function.
fn intercept(req: Request<()>) -> Result<Request<()>, Status> {
// println!("Got a request from {:?}", req.remote_addr());
Ok(req)
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "127.0.0.1:5001".parse().unwrap();
let greeter = MyGreeter::default();
let route_guide = GreeterServer::new(greeter);
let layer = tower::ServiceBuilder::new()
.timeout(Duration::from_secs(10))
.layer(tonic::service::interceptor(intercept))
.layer(MyMiddlewareLayer::default())
// .layer(tower_http::trace::TraceLayer::new_for_http())
.into_inner();
Server::builder()
.layer(layer)
.add_service(route_guide)
.serve(addr)
.await?;
Ok(())
}
#[derive(Debug, Clone, Default)]
struct MyMiddlewareLayer;
impl<S> Layer<S> for MyMiddlewareLayer {
type Service = MyMiddleware<S>;
fn layer(&self, service: S) -> Self::Service {
MyMiddleware { inner: service }
}
}
type BoxFuture<'a, T> = std::pin::Pin<Box<dyn std::future::Future<Output = T> + Send + 'a>>;
#[derive(Debug, Clone)]
struct MyMiddleware<S> {
inner: S,
}
impl<A, T> Service<Request<T>> for MyMiddleware<A>
where
A: Service<Request<T>, Response = Response<T>> + Clone + Send + 'static,
A::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
A::Future: Send + 'static,
{
type Response = Response<T>;
type Error = Box<dyn std::error::Error + Send + Sync>;
type Future = std::pin::Pin<Box<dyn std::future::Future<Output = Result<Self::Response, Self::Error>> + Send + 'static>>;
fn poll_ready(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll<Result<(), Self::Error>> {
todo!()
}
fn call(&mut self, req: Request<T>) -> Self::Future {
todo!()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment