Function to create GRPC server with generic protobuf service and generic tower layer parameters

268 views Asked by At

I'm writing a function fn run_grpc_server<S, L>(service: S, layer: L) -> Result<(), String> where I need to provide generic parameter for protobuf service S and tower layer L, so I can build the GRPC server combining them.

To illustrate, I modify the example https://github.com/hyperium/tonic/blob/master/examples/src/tower/server.rs as follows:

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let greeter = MyGreeter::default();

    // The stack of middleware that our service will be wrapped in
    let layer = tower::ServiceBuilder::new()
        // Apply middleware from tower
        .timeout(Duration::from_secs(30))
        // Apply our own middleware
        .layer(MyMiddlewareLayer::default())
        // Interceptors can be also be applied as middleware
        .layer(tonic::service::interceptor(intercept))
        .into_inner();

    run_grpc_server(greeter, layer).await;

    Ok(())
}

pub async fn run_grpc_server<S, L>(service: S, layer: L) -> Result<(), String>
where
    S: hello_world::greeter_server::Greeter,
    L: Clone, // not sure what other constraints to put here? Something with tower::Layer<?>
{
    let addr = "[::1]:50051".parse().unwrap();

    Server::builder()
        .layer(layer)
        .add_service(GreeterServer::new(service))
        .serve(addr)
        .await
        .map_err(|e| e.to_string())
}

This fails to compile even though the original layer in main is not changed and is now provided as generic parameter L.

The compilation error is:

error[E0277]: the trait bound `L: Layer<Routes>` is not satisfied
  --> src/server.rs:63:10
   |
63 |         .serve(addr)
   |          ^^^^^ the trait `Layer<Routes>` is not implemented for `L`
   |
   = note: required for `Stack<L, Identity>` to implement `Layer<Routes>`
help: consider further restricting this bound
   |
56 |     L: Clone + tower::Layer<tonic::transport::server::Routes>,
   |              ++++++++++++++++++++++++++++++++++++++++++++++++

What changes are needed for run_grpc_server to accept layer as parameter of generic type L ?

Adding compiler suggestion L: Clone + tower::Layer<tonic::transport::server::Routes> doesnt fix the issue but surfaces many more errors

0

There are 0 answers