feat(tonic): make it easier to add tower middleware to servers (#651)

This commit is contained in:
David Pedersen
2021-05-19 09:19:58 +02:00
committed by GitHub
parent 4dda4cbcca
commit 4d2667d1cb
22 changed files with 733 additions and 300 deletions
+3
View File
@@ -20,6 +20,9 @@ tokio-stream = { version = "0.1.5", features = ["net"] }
tower-service = "0.3"
hyper = "0.14"
futures = "0.3"
tower = { version = "0.4", features = [] }
http-body = "0.4"
http = "0.2"
[build-dependencies]
tonic-build = { path = "../../tonic-build" }
@@ -0,0 +1,113 @@
#![allow(unused_variables, dead_code)]
use http_body::Body;
use integration_tests::pb::{test_server, Input, Output};
use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
};
use tonic::{transport::Server, Request, Response, Status};
use tower::{layer::Layer, BoxError, Service};
// all we care about is that this compiles
async fn complex_tower_layers_work() {
struct Svc;
#[tonic::async_trait]
impl test_server::Test for Svc {
async fn unary_call(&self, req: Request<Input>) -> Result<Response<Output>, Status> {
unimplemented!()
}
}
let svc = test_server::TestServer::new(Svc);
Server::builder()
.layer(MyServiceLayer::new())
.add_service(svc)
.serve("127.0.0.1:1322".parse().unwrap())
.await
.unwrap();
}
#[derive(Debug, Clone)]
struct MyServiceLayer {}
impl MyServiceLayer {
fn new() -> Self {
unimplemented!()
}
}
impl<S> Layer<S> for MyServiceLayer {
type Service = MyService<S>;
fn layer(&self, inner: S) -> Self::Service {
unimplemented!()
}
}
#[derive(Debug, Clone)]
struct MyService<S> {
inner: S,
}
impl<S, R, ResBody> Service<R> for MyService<S>
where
S: Service<R, Response = http::Response<ResBody>>,
{
type Response = http::Response<MyBody<ResBody>>;
type Error = BoxError;
type Future = MyFuture<S::Future, ResBody>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
unimplemented!()
}
fn call(&mut self, req: R) -> Self::Future {
unimplemented!()
}
}
struct MyFuture<F, B> {
inner: F,
body: B,
}
impl<F, E, B> Future for MyFuture<F, B>
where
F: Future<Output = Result<http::Response<B>, E>>,
{
type Output = Result<http::Response<MyBody<B>>, BoxError>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
unimplemented!()
}
}
struct MyBody<B> {
inner: B,
}
impl<B> Body for MyBody<B>
where
B: Body,
{
type Data = B::Data;
type Error = BoxError;
fn poll_data(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Self::Data, Self::Error>>> {
unimplemented!()
}
fn poll_trailers(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<Option<http::HeaderMap>, Self::Error>> {
unimplemented!()
}
}