fix(tonic): Remove Sync requirement for streams (#804)
This commit is contained in:
+21
-26
@@ -1,29 +1,24 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"tonic",
|
"tonic",
|
||||||
"tonic-build",
|
"tonic-build",
|
||||||
"tonic-health",
|
"tonic-health",
|
||||||
"tonic-types",
|
"tonic-types",
|
||||||
"tonic-reflection",
|
"tonic-reflection",
|
||||||
"tonic-web",
|
"tonic-web", # Non-published crates
|
||||||
|
"examples",
|
||||||
# Non-published crates
|
"interop", # Tests
|
||||||
"examples",
|
"tests/included_service",
|
||||||
"interop",
|
"tests/same_name",
|
||||||
|
"tests/service_named_service",
|
||||||
# Tests
|
"tests/wellknown",
|
||||||
"tests/included_service",
|
"tests/wellknown-compiled",
|
||||||
"tests/same_name",
|
"tests/extern_path/uuid",
|
||||||
"tests/service_named_service",
|
"tests/ambiguous_methods",
|
||||||
"tests/wellknown",
|
"tests/extern_path/my_application",
|
||||||
"tests/wellknown-compiled",
|
"tests/integration_tests",
|
||||||
"tests/extern_path/uuid",
|
"tests/stream_conflict",
|
||||||
"tests/ambiguous_methods",
|
"tests/root-crate-path",
|
||||||
"tests/extern_path/my_application",
|
"tests/compression",
|
||||||
"tests/integration_tests",
|
"tonic-web/tests/integration",
|
||||||
"tests/stream_conflict",
|
|
||||||
"tests/root-crate-path",
|
|
||||||
"tests/compression",
|
|
||||||
"tonic-web/tests/integration"
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ impl RouteGuide for RouteGuideService {
|
|||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
type RouteChatStream = Pin<Box<dyn Stream<Item = Result<RouteNote, Status>> + Send + Sync + 'static>>;
|
type RouteChatStream = Pin<Box<dyn Stream<Item = Result<RouteNote, Status>> + Send + 'static>>;
|
||||||
|
|
||||||
async fn route_chat(
|
async fn route_chat(
|
||||||
&self,
|
&self,
|
||||||
@@ -493,7 +493,7 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
```rust
|
```rust
|
||||||
type RouteChatStream =
|
type RouteChatStream =
|
||||||
Pin<Box<dyn Stream<Item = Result<RouteNote, Status>> + Send + Sync + 'static>>;
|
Pin<Box<dyn Stream<Item = Result<RouteNote, Status>> + Send + 'static>>;
|
||||||
|
|
||||||
|
|
||||||
async fn route_chat(
|
async fn route_chat(
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use std::pin::Pin;
|
|||||||
use tonic::{metadata::MetadataValue, transport::Server, Request, Response, Status, Streaming};
|
use tonic::{metadata::MetadataValue, transport::Server, Request, Response, Status, Streaming};
|
||||||
|
|
||||||
type EchoResult<T> = Result<Response<T>, Status>;
|
type EchoResult<T> = Result<Response<T>, Status>;
|
||||||
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send + Sync>>;
|
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send>>;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct EchoServer;
|
pub struct EchoServer;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use tonic::{transport::Server, Request, Response, Status, Streaming};
|
|||||||
use pb::{EchoRequest, EchoResponse};
|
use pb::{EchoRequest, EchoResponse};
|
||||||
|
|
||||||
type EchoResult<T> = Result<Response<T>, Status>;
|
type EchoResult<T> = Result<Response<T>, Status>;
|
||||||
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send + Sync>>;
|
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send>>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct EchoServer {
|
pub struct EchoServer {
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ use echo::{
|
|||||||
EchoRequest, EchoResponse,
|
EchoRequest, EchoResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send + Sync>>;
|
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send>>;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct MyGreeter {}
|
pub struct MyGreeter {}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use tonic::{transport::Server, Request, Response, Status, Streaming};
|
|||||||
use pb::{EchoRequest, EchoResponse};
|
use pb::{EchoRequest, EchoResponse};
|
||||||
|
|
||||||
type EchoResult<T> = Result<Response<T>, Status>;
|
type EchoResult<T> = Result<Response<T>, Status>;
|
||||||
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send + Sync>>;
|
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send>>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct EchoServer {
|
pub struct EchoServer {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ use echo::{
|
|||||||
EchoRequest, EchoResponse,
|
EchoRequest, EchoResponse,
|
||||||
};
|
};
|
||||||
|
|
||||||
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send + Sync>>;
|
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send>>;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|||||||
@@ -102,8 +102,7 @@ impl RouteGuide for RouteGuideService {
|
|||||||
Ok(Response::new(summary))
|
Ok(Response::new(summary))
|
||||||
}
|
}
|
||||||
|
|
||||||
type RouteChatStream =
|
type RouteChatStream = Pin<Box<dyn Stream<Item = Result<RouteNote, Status>> + Send + 'static>>;
|
||||||
Pin<Box<dyn Stream<Item = Result<RouteNote, Status>> + Send + Sync + 'static>>;
|
|
||||||
|
|
||||||
async fn route_chat(
|
async fn route_chat(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use tonic::{transport::Server, Request, Response, Status, Streaming};
|
|||||||
use pb::{EchoRequest, EchoResponse};
|
use pb::{EchoRequest, EchoResponse};
|
||||||
|
|
||||||
type EchoResult<T> = Result<Response<T>, Status>;
|
type EchoResult<T> = Result<Response<T>, Status>;
|
||||||
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send + Sync>>;
|
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send>>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct EchoServer {}
|
pub struct EchoServer {}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use tonic::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
type EchoResult<T> = Result<Response<T>, Status>;
|
type EchoResult<T> = Result<Response<T>, Status>;
|
||||||
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send + Sync>>;
|
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send>>;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct EchoServer;
|
pub struct EchoServer;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use tonic::transport::{Certificate, Identity, Server, ServerTlsConfig};
|
|||||||
use tonic::{Request, Response, Status};
|
use tonic::{Request, Response, Status};
|
||||||
|
|
||||||
type EchoResult<T> = Result<Response<T>, Status>;
|
type EchoResult<T> = Result<Response<T>, Status>;
|
||||||
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send + Sync>>;
|
type ResponseStream = Pin<Box<dyn Stream<Item = Result<EchoResponse, Status>> + Send>>;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct EchoServer;
|
pub struct EchoServer;
|
||||||
|
|||||||
@@ -18,9 +18,8 @@ pub struct TestService;
|
|||||||
|
|
||||||
type Result<T> = std::result::Result<Response<T>, Status>;
|
type Result<T> = std::result::Result<Response<T>, Status>;
|
||||||
type Streaming<T> = Request<tonic::Streaming<T>>;
|
type Streaming<T> = Request<tonic::Streaming<T>>;
|
||||||
type Stream<T> = Pin<
|
type Stream<T> =
|
||||||
Box<dyn futures_core::Stream<Item = std::result::Result<T, Status>> + Send + Sync + 'static>,
|
Pin<Box<dyn futures_core::Stream<Item = std::result::Result<T, Status>> + Send + 'static>>;
|
||||||
>;
|
|
||||||
type BoxFuture<T, E> = Pin<Box<dyn Future<Output = std::result::Result<T, E>> + Send + 'static>>;
|
type BoxFuture<T, E> = Pin<Box<dyn Future<Output = std::result::Result<T, E>> + Send + 'static>>;
|
||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ impl test_server::Test for Svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CompressOutputServerStreamStream =
|
type CompressOutputServerStreamStream =
|
||||||
Pin<Box<dyn Stream<Item = Result<SomeData, Status>> + Send + Sync + 'static>>;
|
Pin<Box<dyn Stream<Item = Result<SomeData, Status>> + Send + 'static>>;
|
||||||
|
|
||||||
async fn compress_output_server_stream(
|
async fn compress_output_server_stream(
|
||||||
&self,
|
&self,
|
||||||
@@ -110,7 +110,7 @@ impl test_server::Test for Svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CompressInputOutputBidirectionalStreamStream =
|
type CompressInputOutputBidirectionalStreamStream =
|
||||||
Pin<Box<dyn Stream<Item = Result<SomeData, Status>> + Send + Sync + 'static>>;
|
Pin<Box<dyn Stream<Item = Result<SomeData, Status>> + Send + 'static>>;
|
||||||
|
|
||||||
async fn compress_input_output_bidirectional_stream(
|
async fn compress_input_output_bidirectional_stream(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -12,14 +12,15 @@ version = "0.1.0"
|
|||||||
bytes = "1.0"
|
bytes = "1.0"
|
||||||
futures-util = "0.3"
|
futures-util = "0.3"
|
||||||
prost = "0.9"
|
prost = "0.9"
|
||||||
|
tokio = {version = "1.0", features = ["macros", "rt-multi-thread", "net"]}
|
||||||
tonic = {path = "../../tonic"}
|
tonic = {path = "../../tonic"}
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
async-stream = "0.3"
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
http = "0.2"
|
http = "0.2"
|
||||||
http-body = "0.4"
|
http-body = "0.4"
|
||||||
hyper = "0.14"
|
hyper = "0.14"
|
||||||
tokio = {version = "1.0", features = ["macros", "rt-multi-thread", "net"]}
|
|
||||||
tokio-stream = {version = "0.1.5", features = ["net"]}
|
tokio-stream = {version = "0.1.5", features = ["net"]}
|
||||||
tower = {version = "0.4", features = []}
|
tower = {version = "0.4", features = []}
|
||||||
tower-service = "0.3"
|
tower-service = "0.3"
|
||||||
|
|||||||
@@ -2,3 +2,54 @@ pub mod pb {
|
|||||||
tonic::include_proto!("test");
|
tonic::include_proto!("test");
|
||||||
tonic::include_proto!("stream");
|
tonic::include_proto!("stream");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod mock {
|
||||||
|
use std::{
|
||||||
|
pin::Pin,
|
||||||
|
task::{Context, Poll},
|
||||||
|
};
|
||||||
|
|
||||||
|
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
|
||||||
|
use tonic::transport::server::Connected;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct MockStream(pub tokio::io::DuplexStream);
|
||||||
|
|
||||||
|
impl Connected for MockStream {
|
||||||
|
type ConnectInfo = ();
|
||||||
|
|
||||||
|
/// Create type holding information about the connection.
|
||||||
|
fn connect_info(&self) -> Self::ConnectInfo {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncRead for MockStream {
|
||||||
|
fn poll_read(
|
||||||
|
mut self: Pin<&mut Self>,
|
||||||
|
cx: &mut Context<'_>,
|
||||||
|
buf: &mut ReadBuf<'_>,
|
||||||
|
) -> Poll<std::io::Result<()>> {
|
||||||
|
Pin::new(&mut self.0).poll_read(cx, buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncWrite for MockStream {
|
||||||
|
fn poll_write(
|
||||||
|
mut self: Pin<&mut Self>,
|
||||||
|
cx: &mut Context<'_>,
|
||||||
|
buf: &[u8],
|
||||||
|
) -> Poll<std::io::Result<usize>> {
|
||||||
|
Pin::new(&mut self.0).poll_write(cx, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
|
||||||
|
Pin::new(&mut self.0).poll_flush(cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn poll_shutdown(
|
||||||
|
mut self: Pin<&mut Self>,
|
||||||
|
cx: &mut Context<'_>,
|
||||||
|
) -> Poll<std::io::Result<()>> {
|
||||||
|
Pin::new(&mut self.0).poll_shutdown(cx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures_util::FutureExt;
|
use futures_util::FutureExt;
|
||||||
use http::Uri;
|
use http::Uri;
|
||||||
|
use integration_tests::mock::MockStream;
|
||||||
use integration_tests::pb::{
|
use integration_tests::pb::{
|
||||||
test_client, test_server, test_stream_client, test_stream_server, Input, InputStream, Output,
|
test_client, test_server, test_stream_client, test_stream_server, Input, InputStream, Output,
|
||||||
OutputStream,
|
OutputStream,
|
||||||
@@ -125,9 +126,8 @@ async fn status_with_metadata() {
|
|||||||
jh.await.unwrap();
|
jh.await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
type Stream<T> = std::pin::Pin<
|
type Stream<T> =
|
||||||
Box<dyn futures::Stream<Item = std::result::Result<T, Status>> + Send + Sync + 'static>,
|
std::pin::Pin<Box<dyn futures::Stream<Item = std::result::Result<T, Status>> + Send + 'static>>;
|
||||||
>;
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn status_from_server_stream() {
|
async fn status_from_server_stream() {
|
||||||
@@ -184,7 +184,7 @@ async fn status_from_server_stream_with_source() {
|
|||||||
let channel = Endpoint::try_from("http://[::]:50051")
|
let channel = Endpoint::try_from("http://[::]:50051")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.connect_with_connector_lazy(tower::service_fn(move |_: Uri| async move {
|
.connect_with_connector_lazy(tower::service_fn(move |_: Uri| async move {
|
||||||
Err::<mock::MockStream, _>(std::io::Error::new(std::io::ErrorKind::Other, "WTF"))
|
Err::<MockStream, _>(std::io::Error::new(std::io::ErrorKind::Other, "WTF"))
|
||||||
}))
|
}))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -201,54 +201,3 @@ fn trace_init() {
|
|||||||
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
|
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
|
||||||
.try_init();
|
.try_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
mod mock {
|
|
||||||
use std::{
|
|
||||||
pin::Pin,
|
|
||||||
task::{Context, Poll},
|
|
||||||
};
|
|
||||||
|
|
||||||
use tokio::io::{AsyncRead, AsyncWrite, ReadBuf};
|
|
||||||
use tonic::transport::server::Connected;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct MockStream(pub tokio::io::DuplexStream);
|
|
||||||
|
|
||||||
impl Connected for MockStream {
|
|
||||||
type ConnectInfo = ();
|
|
||||||
|
|
||||||
/// Create type holding information about the connection.
|
|
||||||
fn connect_info(&self) -> Self::ConnectInfo {}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsyncRead for MockStream {
|
|
||||||
fn poll_read(
|
|
||||||
mut self: Pin<&mut Self>,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
buf: &mut ReadBuf<'_>,
|
|
||||||
) -> Poll<std::io::Result<()>> {
|
|
||||||
Pin::new(&mut self.0).poll_read(cx, buf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsyncWrite for MockStream {
|
|
||||||
fn poll_write(
|
|
||||||
mut self: Pin<&mut Self>,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
buf: &[u8],
|
|
||||||
) -> Poll<std::io::Result<usize>> {
|
|
||||||
Pin::new(&mut self.0).poll_write(cx, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
|
|
||||||
Pin::new(&mut self.0).poll_flush(cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_shutdown(
|
|
||||||
mut self: Pin<&mut Self>,
|
|
||||||
cx: &mut Context<'_>,
|
|
||||||
) -> Poll<std::io::Result<()>> {
|
|
||||||
Pin::new(&mut self.0).poll_shutdown(cx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
use futures::FutureExt;
|
||||||
|
use integration_tests::pb::{test_stream_server, InputStream, OutputStream};
|
||||||
|
use tonic::{transport::Server, Request, Response, Status};
|
||||||
|
|
||||||
|
type Stream<T> =
|
||||||
|
std::pin::Pin<Box<dyn futures::Stream<Item = std::result::Result<T, Status>> + Send + 'static>>;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn status_from_server_stream_with_source() {
|
||||||
|
struct Svc;
|
||||||
|
|
||||||
|
#[tonic::async_trait]
|
||||||
|
impl test_stream_server::TestStream for Svc {
|
||||||
|
type StreamCallStream = Stream<OutputStream>;
|
||||||
|
|
||||||
|
async fn stream_call(
|
||||||
|
&self,
|
||||||
|
_: Request<InputStream>,
|
||||||
|
) -> Result<Response<Self::StreamCallStream>, Status> {
|
||||||
|
let s = Unsync(0 as *mut ());
|
||||||
|
|
||||||
|
Ok(Response::new(Box::pin(s) as Self::StreamCallStream))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let svc = test_stream_server::TestStreamServer::new(Svc);
|
||||||
|
|
||||||
|
Server::builder()
|
||||||
|
.add_service(svc)
|
||||||
|
.serve("127.0.0.1:1339".parse().unwrap())
|
||||||
|
.now_or_never();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Unsync(*mut ());
|
||||||
|
|
||||||
|
unsafe impl Send for Unsync {}
|
||||||
|
|
||||||
|
impl futures::Stream for Unsync {
|
||||||
|
type Item = Result<OutputStream, Status>;
|
||||||
|
|
||||||
|
fn poll_next(
|
||||||
|
self: std::pin::Pin<&mut Self>,
|
||||||
|
_cx: &mut std::task::Context<'_>,
|
||||||
|
) -> std::task::Poll<Option<Self::Item>> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -57,7 +57,7 @@ pub fn generate<T: Service>(
|
|||||||
impl<T> #service_ident<T>
|
impl<T> #service_ident<T>
|
||||||
where
|
where
|
||||||
T: tonic::client::GrpcService<tonic::body::BoxBody>,
|
T: tonic::client::GrpcService<tonic::body::BoxBody>,
|
||||||
T::ResponseBody: Body + Send + Sync + 'static,
|
T::ResponseBody: Body + Send + 'static,
|
||||||
T::Error: Into<StdError>,
|
T::Error: Into<StdError>,
|
||||||
<T::ResponseBody as Body>::Error: Into<StdError> + Send,
|
<T::ResponseBody as Body>::Error: Into<StdError> + Send,
|
||||||
{
|
{
|
||||||
@@ -203,8 +203,8 @@ fn generate_server_streaming<T: Method>(
|
|||||||
tonic::Status::new(tonic::Code::Unknown, format!("Service was not ready: {}", e.into()))
|
tonic::Status::new(tonic::Code::Unknown, format!("Service was not ready: {}", e.into()))
|
||||||
})?;
|
})?;
|
||||||
let codec = #codec_name::default();
|
let codec = #codec_name::default();
|
||||||
let path = http::uri::PathAndQuery::from_static(#path);
|
let path = http::uri::PathAndQuery::from_static(#path);
|
||||||
self.inner.server_streaming(request.into_request(), path, codec).await
|
self.inner.server_streaming(request.into_request(), path, codec).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -255,8 +255,8 @@ fn generate_streaming<T: Method>(
|
|||||||
tonic::Status::new(tonic::Code::Unknown, format!("Service was not ready: {}", e.into()))
|
tonic::Status::new(tonic::Code::Unknown, format!("Service was not ready: {}", e.into()))
|
||||||
})?;
|
})?;
|
||||||
let codec = #codec_name::default();
|
let codec = #codec_name::default();
|
||||||
let path = http::uri::PathAndQuery::from_static(#path);
|
let path = http::uri::PathAndQuery::from_static(#path);
|
||||||
self.inner.streaming(request.into_streaming_request(), path, codec).await
|
self.inner.streaming(request.into_streaming_request(), path, codec).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ pub fn generate<T: Service>(
|
|||||||
impl<T, B> tonic::codegen::Service<http::Request<B>> for #server_service<T>
|
impl<T, B> tonic::codegen::Service<http::Request<B>> for #server_service<T>
|
||||||
where
|
where
|
||||||
T: #server_trait,
|
T: #server_trait,
|
||||||
B: Body + Send + Sync + 'static,
|
B: Body + Send + 'static,
|
||||||
B::Error: Into<StdError> + Send + 'static,
|
B::Error: Into<StdError> + Send + 'static,
|
||||||
{
|
{
|
||||||
type Response = http::Response<tonic::body::BoxBody>;
|
type Response = http::Response<tonic::body::BoxBody>;
|
||||||
@@ -232,7 +232,7 @@ fn generate_trait_methods<T: Service>(
|
|||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#stream_doc
|
#stream_doc
|
||||||
type #stream: futures_core::Stream<Item = Result<#res_message, tonic::Status>> + Send + Sync + 'static;
|
type #stream: futures_core::Stream<Item = Result<#res_message, tonic::Status>> + Send + 'static;
|
||||||
|
|
||||||
#method_doc
|
#method_doc
|
||||||
async fn #name(&self, request: tonic::Request<#req_message>)
|
async fn #name(&self, request: tonic::Request<#req_message>)
|
||||||
@@ -248,7 +248,7 @@ fn generate_trait_methods<T: Service>(
|
|||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#stream_doc
|
#stream_doc
|
||||||
type #stream: futures_core::Stream<Item = Result<#res_message, tonic::Status>> + Send + Sync + 'static;
|
type #stream: futures_core::Stream<Item = Result<#res_message, tonic::Status>> + Send + 'static;
|
||||||
|
|
||||||
#method_doc
|
#method_doc
|
||||||
async fn #name(&self, request: tonic::Request<tonic::Streaming<#req_message>>)
|
async fn #name(&self, request: tonic::Request<tonic::Streaming<#req_message>>)
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ impl Health for HealthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type WatchStream =
|
type WatchStream =
|
||||||
Pin<Box<dyn Stream<Item = Result<HealthCheckResponse, Status>> + Send + Sync + 'static>>;
|
Pin<Box<dyn Stream<Item = Result<HealthCheckResponse, Status>> + Send + 'static>>;
|
||||||
|
|
||||||
async fn watch(
|
async fn watch(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ pub mod pb {
|
|||||||
tonic::include_proto!("test");
|
tonic::include_proto!("test");
|
||||||
}
|
}
|
||||||
|
|
||||||
type BoxStream<T> = Pin<Box<dyn Stream<Item = Result<T, Status>> + Send + Sync + 'static>>;
|
type BoxStream<T> = Pin<Box<dyn Stream<Item = Result<T, Status>> + Send + 'static>>;
|
||||||
|
|
||||||
pub struct Svc;
|
pub struct Svc;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -55,7 +55,7 @@ http = "0.2"
|
|||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
|
||||||
async-stream = "0.3"
|
async-stream = "0.3"
|
||||||
http-body = "0.4.2"
|
http-body = "0.4.4"
|
||||||
percent-encoding = "2.1"
|
percent-encoding = "2.1"
|
||||||
pin-project = "1.0"
|
pin-project = "1.0"
|
||||||
tokio-util = {version = "0.6", features = ["codec"]}
|
tokio-util = {version = "0.6", features = ["codec"]}
|
||||||
@@ -71,7 +71,7 @@ async-trait = {version = "0.1.13", optional = true}
|
|||||||
|
|
||||||
# transport
|
# transport
|
||||||
h2 = {version = "0.3", optional = true}
|
h2 = {version = "0.3", optional = true}
|
||||||
hyper = {version = "0.14.2", features = ["full"], optional = true}
|
hyper = {version = "0.14.4", features = ["full"], optional = true}
|
||||||
hyper-timeout = {version = "0.4", optional = true}
|
hyper-timeout = {version = "0.4", optional = true}
|
||||||
tokio = {version = "1.0.1", features = ["net"], optional = true}
|
tokio = {version = "1.0.1", features = ["net"], optional = true}
|
||||||
tokio-stream = "0.1"
|
tokio-stream = "0.1"
|
||||||
|
|||||||
+4
-2
@@ -3,11 +3,13 @@
|
|||||||
use http_body::Body;
|
use http_body::Body;
|
||||||
|
|
||||||
/// A type erased HTTP body used for tonic services.
|
/// A type erased HTTP body used for tonic services.
|
||||||
pub type BoxBody = http_body::combinators::BoxBody<bytes::Bytes, crate::Status>;
|
pub type BoxBody = http_body::combinators::UnsyncBoxBody<bytes::Bytes, crate::Status>;
|
||||||
|
|
||||||
// this also exists in `crate::codegen` but we need it here since `codegen` has
|
// this also exists in `crate::codegen` but we need it here since `codegen` has
|
||||||
// `#[cfg(feature = "codegen")]`.
|
// `#[cfg(feature = "codegen")]`.
|
||||||
/// Create an empty `BoxBody`
|
/// Create an empty `BoxBody`
|
||||||
pub fn empty_body() -> BoxBody {
|
pub fn empty_body() -> BoxBody {
|
||||||
http_body::Empty::new().map_err(|err| match err {}).boxed()
|
http_body::Empty::new()
|
||||||
|
.map_err(|err| match err {})
|
||||||
|
.boxed_unsync()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ impl<T> Grpc<T> {
|
|||||||
) -> Result<Response<M2>, Status>
|
) -> Result<Response<M2>, Status>
|
||||||
where
|
where
|
||||||
T: GrpcService<BoxBody>,
|
T: GrpcService<BoxBody>,
|
||||||
T::ResponseBody: Body + Send + Sync + 'static,
|
T::ResponseBody: Body + Send + 'static,
|
||||||
<T::ResponseBody as Body>::Error: Into<crate::Error>,
|
<T::ResponseBody as Body>::Error: Into<crate::Error>,
|
||||||
C: Codec<Encode = M1, Decode = M2>,
|
C: Codec<Encode = M1, Decode = M2>,
|
||||||
M1: Send + Sync + 'static,
|
M1: Send + Sync + 'static,
|
||||||
@@ -169,9 +169,9 @@ impl<T> Grpc<T> {
|
|||||||
) -> Result<Response<M2>, Status>
|
) -> Result<Response<M2>, Status>
|
||||||
where
|
where
|
||||||
T: GrpcService<BoxBody>,
|
T: GrpcService<BoxBody>,
|
||||||
T::ResponseBody: Body + Send + Sync + 'static,
|
T::ResponseBody: Body + Send + 'static,
|
||||||
<T::ResponseBody as Body>::Error: Into<crate::Error>,
|
<T::ResponseBody as Body>::Error: Into<crate::Error>,
|
||||||
S: Stream<Item = M1> + Send + Sync + 'static,
|
S: Stream<Item = M1> + Send + 'static,
|
||||||
C: Codec<Encode = M1, Decode = M2>,
|
C: Codec<Encode = M1, Decode = M2>,
|
||||||
M1: Send + Sync + 'static,
|
M1: Send + Sync + 'static,
|
||||||
M2: Send + Sync + 'static,
|
M2: Send + Sync + 'static,
|
||||||
@@ -206,7 +206,7 @@ impl<T> Grpc<T> {
|
|||||||
) -> Result<Response<Streaming<M2>>, Status>
|
) -> Result<Response<Streaming<M2>>, Status>
|
||||||
where
|
where
|
||||||
T: GrpcService<BoxBody>,
|
T: GrpcService<BoxBody>,
|
||||||
T::ResponseBody: Body + Send + Sync + 'static,
|
T::ResponseBody: Body + Send + 'static,
|
||||||
<T::ResponseBody as Body>::Error: Into<crate::Error>,
|
<T::ResponseBody as Body>::Error: Into<crate::Error>,
|
||||||
C: Codec<Encode = M1, Decode = M2>,
|
C: Codec<Encode = M1, Decode = M2>,
|
||||||
M1: Send + Sync + 'static,
|
M1: Send + Sync + 'static,
|
||||||
@@ -225,9 +225,9 @@ impl<T> Grpc<T> {
|
|||||||
) -> Result<Response<Streaming<M2>>, Status>
|
) -> Result<Response<Streaming<M2>>, Status>
|
||||||
where
|
where
|
||||||
T: GrpcService<BoxBody>,
|
T: GrpcService<BoxBody>,
|
||||||
T::ResponseBody: Body + Send + Sync + 'static,
|
T::ResponseBody: Body + Send + 'static,
|
||||||
<T::ResponseBody as Body>::Error: Into<crate::Error>,
|
<T::ResponseBody as Body>::Error: Into<crate::Error>,
|
||||||
S: Stream<Item = M1> + Send + Sync + 'static,
|
S: Stream<Item = M1> + Send + 'static,
|
||||||
C: Codec<Encode = M1, Decode = M2>,
|
C: Codec<Encode = M1, Decode = M2>,
|
||||||
M1: Send + Sync + 'static,
|
M1: Send + Sync + 'static,
|
||||||
M2: Send + Sync + 'static,
|
M2: Send + Sync + 'static,
|
||||||
|
|||||||
+12
-12
@@ -21,7 +21,7 @@ const BUFFER_SIZE: usize = 8 * 1024;
|
|||||||
/// This will wrap some inner [`Body`] and [`Decoder`] and provide an interface
|
/// This will wrap some inner [`Body`] and [`Decoder`] and provide an interface
|
||||||
/// to fetch the message stream and trailing metadata
|
/// to fetch the message stream and trailing metadata
|
||||||
pub struct Streaming<T> {
|
pub struct Streaming<T> {
|
||||||
decoder: Box<dyn Decoder<Item = T, Error = Status> + Send + Sync + 'static>,
|
decoder: Box<dyn Decoder<Item = T, Error = Status> + Send + 'static>,
|
||||||
body: BoxBody,
|
body: BoxBody,
|
||||||
state: State,
|
state: State,
|
||||||
direction: Direction,
|
direction: Direction,
|
||||||
@@ -56,9 +56,9 @@ impl<T> Streaming<T> {
|
|||||||
#[cfg(feature = "compression")] encoding: Option<CompressionEncoding>,
|
#[cfg(feature = "compression")] encoding: Option<CompressionEncoding>,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
B: Body + Send + Sync + 'static,
|
B: Body + Send + 'static,
|
||||||
B::Error: Into<crate::Error>,
|
B::Error: Into<crate::Error>,
|
||||||
D: Decoder<Item = T, Error = Status> + Send + Sync + 'static,
|
D: Decoder<Item = T, Error = Status> + Send + 'static,
|
||||||
{
|
{
|
||||||
Self::new(
|
Self::new(
|
||||||
decoder,
|
decoder,
|
||||||
@@ -71,9 +71,9 @@ impl<T> Streaming<T> {
|
|||||||
|
|
||||||
pub(crate) fn new_empty<B, D>(decoder: D, body: B) -> Self
|
pub(crate) fn new_empty<B, D>(decoder: D, body: B) -> Self
|
||||||
where
|
where
|
||||||
B: Body + Send + Sync + 'static,
|
B: Body + Send + 'static,
|
||||||
B::Error: Into<crate::Error>,
|
B::Error: Into<crate::Error>,
|
||||||
D: Decoder<Item = T, Error = Status> + Send + Sync + 'static,
|
D: Decoder<Item = T, Error = Status> + Send + 'static,
|
||||||
{
|
{
|
||||||
Self::new(
|
Self::new(
|
||||||
decoder,
|
decoder,
|
||||||
@@ -91,9 +91,9 @@ impl<T> Streaming<T> {
|
|||||||
#[cfg(feature = "compression")] encoding: Option<CompressionEncoding>,
|
#[cfg(feature = "compression")] encoding: Option<CompressionEncoding>,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
B: Body + Send + Sync + 'static,
|
B: Body + Send + 'static,
|
||||||
B::Error: Into<crate::Error>,
|
B::Error: Into<crate::Error>,
|
||||||
D: Decoder<Item = T, Error = Status> + Send + Sync + 'static,
|
D: Decoder<Item = T, Error = Status> + Send + 'static,
|
||||||
{
|
{
|
||||||
Self::new(
|
Self::new(
|
||||||
decoder,
|
decoder,
|
||||||
@@ -111,16 +111,16 @@ impl<T> Streaming<T> {
|
|||||||
#[cfg(feature = "compression")] encoding: Option<CompressionEncoding>,
|
#[cfg(feature = "compression")] encoding: Option<CompressionEncoding>,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
B: Body + Send + Sync + 'static,
|
B: Body + Send + 'static,
|
||||||
B::Error: Into<crate::Error>,
|
B::Error: Into<crate::Error>,
|
||||||
D: Decoder<Item = T, Error = Status> + Send + Sync + 'static,
|
D: Decoder<Item = T, Error = Status> + Send + 'static,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
decoder: Box::new(decoder),
|
decoder: Box::new(decoder),
|
||||||
body: body
|
body: body
|
||||||
.map_data(|mut buf| buf.copy_to_bytes(buf.remaining()))
|
.map_data(|mut buf| buf.copy_to_bytes(buf.remaining()))
|
||||||
.map_err(|err| Status::map_error(err.into()))
|
.map_err(|err| Status::map_error(err.into()))
|
||||||
.boxed(),
|
.boxed_unsync(),
|
||||||
state: State::ReadHeader,
|
state: State::ReadHeader,
|
||||||
direction,
|
direction,
|
||||||
buf: BytesMut::with_capacity(BUFFER_SIZE),
|
buf: BytesMut::with_capacity(BUFFER_SIZE),
|
||||||
@@ -140,7 +140,7 @@ impl<T> Streaming<T> {
|
|||||||
/// # use std::fmt::Debug;
|
/// # use std::fmt::Debug;
|
||||||
/// # async fn next_message_ex<T, D>(mut request: Streaming<T>) -> Result<(), Status>
|
/// # async fn next_message_ex<T, D>(mut request: Streaming<T>) -> Result<(), Status>
|
||||||
/// # where T: Debug,
|
/// # where T: Debug,
|
||||||
/// # D: Decoder<Item = T, Error = Status> + Send + Sync + 'static,
|
/// # D: Decoder<Item = T, Error = Status> + Send + 'static,
|
||||||
/// # {
|
/// # {
|
||||||
/// if let Some(next_message) = request.message().await? {
|
/// if let Some(next_message) = request.message().await? {
|
||||||
/// println!("{:?}", next_message);
|
/// println!("{:?}", next_message);
|
||||||
@@ -378,4 +378,4 @@ impl<T> fmt::Debug for Streaming<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
static_assertions::assert_impl_all!(Streaming<()>: Send, Sync);
|
static_assertions::assert_impl_all!(Streaming<()>: Send);
|
||||||
|
|||||||
@@ -22,9 +22,8 @@ pub(crate) fn encode_server<T, U>(
|
|||||||
#[cfg(feature = "compression")] compression_override: SingleMessageCompressionOverride,
|
#[cfg(feature = "compression")] compression_override: SingleMessageCompressionOverride,
|
||||||
) -> EncodeBody<impl Stream<Item = Result<Bytes, Status>>>
|
) -> EncodeBody<impl Stream<Item = Result<Bytes, Status>>>
|
||||||
where
|
where
|
||||||
T: Encoder<Error = Status> + Send + Sync + 'static,
|
T: Encoder<Error = Status>,
|
||||||
T::Item: Send + Sync,
|
U: Stream<Item = Result<T::Item, Status>>,
|
||||||
U: Stream<Item = Result<T::Item, Status>> + Send + Sync + 'static,
|
|
||||||
{
|
{
|
||||||
let stream = encode(
|
let stream = encode(
|
||||||
encoder,
|
encoder,
|
||||||
@@ -45,9 +44,8 @@ pub(crate) fn encode_client<T, U>(
|
|||||||
#[cfg(feature = "compression")] compression_encoding: Option<CompressionEncoding>,
|
#[cfg(feature = "compression")] compression_encoding: Option<CompressionEncoding>,
|
||||||
) -> EncodeBody<impl Stream<Item = Result<Bytes, Status>>>
|
) -> EncodeBody<impl Stream<Item = Result<Bytes, Status>>>
|
||||||
where
|
where
|
||||||
T: Encoder<Error = Status> + Send + Sync + 'static,
|
T: Encoder<Error = Status>,
|
||||||
T::Item: Send + Sync,
|
U: Stream<Item = T::Item>,
|
||||||
U: Stream<Item = T::Item> + Send + Sync + 'static,
|
|
||||||
{
|
{
|
||||||
let stream = encode(
|
let stream = encode(
|
||||||
encoder,
|
encoder,
|
||||||
@@ -157,7 +155,7 @@ pub(crate) struct EncodeBody<S> {
|
|||||||
|
|
||||||
impl<S> EncodeBody<S>
|
impl<S> EncodeBody<S>
|
||||||
where
|
where
|
||||||
S: Stream<Item = Result<Bytes, Status>> + Send + Sync + 'static,
|
S: Stream<Item = Result<Bytes, Status>>,
|
||||||
{
|
{
|
||||||
pub(crate) fn new_client(inner: S) -> Self {
|
pub(crate) fn new_client(inner: S) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ pub trait Codec: Default {
|
|||||||
type Decode: Send + 'static;
|
type Decode: Send + 'static;
|
||||||
|
|
||||||
/// The encoder that can encode a message.
|
/// The encoder that can encode a message.
|
||||||
type Encoder: Encoder<Item = Self::Encode, Error = Status> + Send + Sync + 'static;
|
type Encoder: Encoder<Item = Self::Encode, Error = Status> + Send + 'static;
|
||||||
/// The encoder that can decode a message.
|
/// The encoder that can decode a message.
|
||||||
type Decoder: Decoder<Item = Self::Decode, Error = Status> + Send + Sync + 'static;
|
type Decoder: Decoder<Item = Self::Decode, Error = Status> + Send + 'static;
|
||||||
|
|
||||||
/// Fetch the encoder.
|
/// Fetch the encoder.
|
||||||
fn encoder(&mut self) -> Self::Encoder;
|
fn encoder(&mut self) -> Self::Encoder;
|
||||||
|
|||||||
@@ -35,5 +35,7 @@ impl std::fmt::Display for Never {
|
|||||||
impl std::error::Error for Never {}
|
impl std::error::Error for Never {}
|
||||||
|
|
||||||
pub fn empty_body() -> crate::body::BoxBody {
|
pub fn empty_body() -> crate::body::BoxBody {
|
||||||
http_body::Empty::new().map_err(|err| match err {}).boxed()
|
http_body::Empty::new()
|
||||||
|
.map_err(|err| match err {})
|
||||||
|
.boxed_unsync()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ pub trait IntoRequest<T>: sealed::Sealed {
|
|||||||
/// ```
|
/// ```
|
||||||
pub trait IntoStreamingRequest: sealed::Sealed {
|
pub trait IntoStreamingRequest: sealed::Sealed {
|
||||||
/// The RPC request stream type
|
/// The RPC request stream type
|
||||||
type Stream: Stream<Item = Self::Message> + Send + Sync + 'static;
|
type Stream: Stream<Item = Self::Message> + Send + 'static;
|
||||||
|
|
||||||
/// The RPC request type
|
/// The RPC request type
|
||||||
type Message;
|
type Message;
|
||||||
@@ -357,7 +357,7 @@ impl<T> IntoRequest<T> for Request<T> {
|
|||||||
|
|
||||||
impl<T> IntoStreamingRequest for T
|
impl<T> IntoStreamingRequest for T
|
||||||
where
|
where
|
||||||
T: Stream + Send + Sync + 'static,
|
T: Stream + Send + 'static,
|
||||||
{
|
{
|
||||||
type Stream = T;
|
type Stream = T;
|
||||||
type Message = T::Item;
|
type Message = T::Item;
|
||||||
@@ -369,7 +369,7 @@ where
|
|||||||
|
|
||||||
impl<T> IntoStreamingRequest for Request<T>
|
impl<T> IntoStreamingRequest for Request<T>
|
||||||
where
|
where
|
||||||
T: Stream + Send + Sync + 'static,
|
T: Stream + Send + 'static,
|
||||||
{
|
{
|
||||||
type Stream = T;
|
type Stream = T;
|
||||||
type Message = T::Item;
|
type Message = T::Item;
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ pub struct Grpc<T> {
|
|||||||
impl<T> Grpc<T>
|
impl<T> Grpc<T>
|
||||||
where
|
where
|
||||||
T: Codec,
|
T: Codec,
|
||||||
T::Encode: Sync,
|
|
||||||
{
|
{
|
||||||
/// Creates a new gRPC server with the provided [`Codec`].
|
/// Creates a new gRPC server with the provided [`Codec`].
|
||||||
pub fn new(codec: T) -> Self {
|
pub fn new(codec: T) -> Self {
|
||||||
@@ -173,7 +172,7 @@ where
|
|||||||
) -> http::Response<BoxBody>
|
) -> http::Response<BoxBody>
|
||||||
where
|
where
|
||||||
S: UnaryService<T::Decode, Response = T::Encode>,
|
S: UnaryService<T::Decode, Response = T::Encode>,
|
||||||
B: Body + Send + Sync + 'static,
|
B: Body + Send + 'static,
|
||||||
B::Error: Into<crate::Error> + Send,
|
B::Error: Into<crate::Error> + Send,
|
||||||
{
|
{
|
||||||
#[cfg(feature = "compression")]
|
#[cfg(feature = "compression")]
|
||||||
@@ -221,8 +220,8 @@ where
|
|||||||
) -> http::Response<BoxBody>
|
) -> http::Response<BoxBody>
|
||||||
where
|
where
|
||||||
S: ServerStreamingService<T::Decode, Response = T::Encode>,
|
S: ServerStreamingService<T::Decode, Response = T::Encode>,
|
||||||
S::ResponseStream: Send + Sync + 'static,
|
S::ResponseStream: Send + 'static,
|
||||||
B: Body + Send + Sync + 'static,
|
B: Body + Send + 'static,
|
||||||
B::Error: Into<crate::Error> + Send,
|
B::Error: Into<crate::Error> + Send,
|
||||||
{
|
{
|
||||||
#[cfg(feature = "compression")]
|
#[cfg(feature = "compression")]
|
||||||
@@ -265,7 +264,7 @@ where
|
|||||||
) -> http::Response<BoxBody>
|
) -> http::Response<BoxBody>
|
||||||
where
|
where
|
||||||
S: ClientStreamingService<T::Decode, Response = T::Encode>,
|
S: ClientStreamingService<T::Decode, Response = T::Encode>,
|
||||||
B: Body + Send + Sync + 'static,
|
B: Body + Send + 'static,
|
||||||
B::Error: Into<crate::Error> + Send + 'static,
|
B::Error: Into<crate::Error> + Send + 'static,
|
||||||
{
|
{
|
||||||
#[cfg(feature = "compression")]
|
#[cfg(feature = "compression")]
|
||||||
@@ -301,8 +300,8 @@ where
|
|||||||
) -> http::Response<BoxBody>
|
) -> http::Response<BoxBody>
|
||||||
where
|
where
|
||||||
S: StreamingService<T::Decode, Response = T::Encode> + Send,
|
S: StreamingService<T::Decode, Response = T::Encode> + Send,
|
||||||
S::ResponseStream: Send + Sync + 'static,
|
S::ResponseStream: Send + 'static,
|
||||||
B: Body + Send + Sync + 'static,
|
B: Body + Send + 'static,
|
||||||
B::Error: Into<crate::Error> + Send,
|
B::Error: Into<crate::Error> + Send,
|
||||||
{
|
{
|
||||||
#[cfg(feature = "compression")]
|
#[cfg(feature = "compression")]
|
||||||
@@ -329,7 +328,7 @@ where
|
|||||||
request: http::Request<B>,
|
request: http::Request<B>,
|
||||||
) -> Result<Request<T::Decode>, Status>
|
) -> Result<Request<T::Decode>, Status>
|
||||||
where
|
where
|
||||||
B: Body + Send + Sync + 'static,
|
B: Body + Send + 'static,
|
||||||
B::Error: Into<crate::Error> + Send,
|
B::Error: Into<crate::Error> + Send,
|
||||||
{
|
{
|
||||||
#[cfg(feature = "compression")]
|
#[cfg(feature = "compression")]
|
||||||
@@ -365,7 +364,7 @@ where
|
|||||||
request: http::Request<B>,
|
request: http::Request<B>,
|
||||||
) -> Result<Request<Streaming<T::Decode>>, Status>
|
) -> Result<Request<Streaming<T::Decode>>, Status>
|
||||||
where
|
where
|
||||||
B: Body + Send + Sync + 'static,
|
B: Body + Send + 'static,
|
||||||
B::Error: Into<crate::Error> + Send,
|
B::Error: Into<crate::Error> + Send,
|
||||||
{
|
{
|
||||||
#[cfg(feature = "compression")]
|
#[cfg(feature = "compression")]
|
||||||
@@ -388,7 +387,7 @@ where
|
|||||||
#[cfg(feature = "compression")] compression_override: SingleMessageCompressionOverride,
|
#[cfg(feature = "compression")] compression_override: SingleMessageCompressionOverride,
|
||||||
) -> http::Response<BoxBody>
|
) -> http::Response<BoxBody>
|
||||||
where
|
where
|
||||||
B: TryStream<Ok = T::Encode, Error = Status> + Send + Sync + 'static,
|
B: TryStream<Ok = T::Encode, Error = Status> + Send + 'static,
|
||||||
{
|
{
|
||||||
let response = match response {
|
let response = match response {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ use tower::{
|
|||||||
Service, ServiceBuilder,
|
Service, ServiceBuilder,
|
||||||
};
|
};
|
||||||
|
|
||||||
type BoxHttpBody = http_body::combinators::BoxBody<Bytes, crate::Error>;
|
type BoxHttpBody = http_body::combinators::UnsyncBoxBody<Bytes, crate::Error>;
|
||||||
type BoxService = tower::util::BoxService<Request<Body>, Response<BoxHttpBody>, crate::Error>;
|
type BoxService = tower::util::BoxService<Request<Body>, Response<BoxHttpBody>, crate::Error>;
|
||||||
type TraceInterceptor = Arc<dyn Fn(&http::Request<()>) -> tracing::Span + Send + Sync + 'static>;
|
type TraceInterceptor = Arc<dyn Fn(&http::Request<()>) -> tracing::Span + Send + Sync + 'static>;
|
||||||
|
|
||||||
@@ -465,7 +465,7 @@ impl<L> Server<L> {
|
|||||||
IO::ConnectInfo: Clone + Send + Sync + 'static,
|
IO::ConnectInfo: Clone + Send + Sync + 'static,
|
||||||
IE: Into<crate::Error>,
|
IE: Into<crate::Error>,
|
||||||
F: Future<Output = ()>,
|
F: Future<Output = ()>,
|
||||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
ResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||||
ResBody::Error: Into<crate::Error>,
|
ResBody::Error: Into<crate::Error>,
|
||||||
{
|
{
|
||||||
let trace_interceptor = self.trace_interceptor.clone();
|
let trace_interceptor = self.trace_interceptor.clone();
|
||||||
@@ -627,7 +627,7 @@ where
|
|||||||
Send + 'static,
|
Send + 'static,
|
||||||
<<L as Layer<Routes<A, B, Request<Body>>>>::Service as Service<Request<Body>>>::Error:
|
<<L as Layer<Routes<A, B, Request<Body>>>>::Service as Service<Request<Body>>>::Error:
|
||||||
Into<crate::Error> + Send,
|
Into<crate::Error> + Send,
|
||||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
ResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||||
ResBody::Error: Into<crate::Error>,
|
ResBody::Error: Into<crate::Error>,
|
||||||
{
|
{
|
||||||
let incoming = TcpIncoming::new(addr, self.server.tcp_nodelay, self.server.tcp_keepalive)
|
let incoming = TcpIncoming::new(addr, self.server.tcp_nodelay, self.server.tcp_keepalive)
|
||||||
@@ -659,7 +659,7 @@ where
|
|||||||
Send + 'static,
|
Send + 'static,
|
||||||
<<L as Layer<Routes<A, B, Request<Body>>>>::Service as Service<Request<Body>>>::Error:
|
<<L as Layer<Routes<A, B, Request<Body>>>>::Service as Service<Request<Body>>>::Error:
|
||||||
Into<crate::Error> + Send,
|
Into<crate::Error> + Send,
|
||||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
ResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||||
ResBody::Error: Into<crate::Error>,
|
ResBody::Error: Into<crate::Error>,
|
||||||
{
|
{
|
||||||
let incoming = TcpIncoming::new(addr, self.server.tcp_nodelay, self.server.tcp_keepalive)
|
let incoming = TcpIncoming::new(addr, self.server.tcp_nodelay, self.server.tcp_keepalive)
|
||||||
@@ -688,7 +688,7 @@ where
|
|||||||
Send + 'static,
|
Send + 'static,
|
||||||
<<L as Layer<Routes<A, B, Request<Body>>>>::Service as Service<Request<Body>>>::Error:
|
<<L as Layer<Routes<A, B, Request<Body>>>>::Service as Service<Request<Body>>>::Error:
|
||||||
Into<crate::Error> + Send,
|
Into<crate::Error> + Send,
|
||||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
ResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||||
ResBody::Error: Into<crate::Error>,
|
ResBody::Error: Into<crate::Error>,
|
||||||
{
|
{
|
||||||
self.server
|
self.server
|
||||||
@@ -723,7 +723,7 @@ where
|
|||||||
Send + 'static,
|
Send + 'static,
|
||||||
<<L as Layer<Routes<A, B, Request<Body>>>>::Service as Service<Request<Body>>>::Error:
|
<<L as Layer<Routes<A, B, Request<Body>>>>::Service as Service<Request<Body>>>::Error:
|
||||||
Into<crate::Error> + Send,
|
Into<crate::Error> + Send,
|
||||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
ResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||||
ResBody::Error: Into<crate::Error>,
|
ResBody::Error: Into<crate::Error>,
|
||||||
{
|
{
|
||||||
self.server
|
self.server
|
||||||
@@ -740,7 +740,7 @@ where
|
|||||||
Send + 'static,
|
Send + 'static,
|
||||||
<<L as Layer<Routes<A, B, Request<Body>>>>::Service as Service<Request<Body>>>::Error:
|
<<L as Layer<Routes<A, B, Request<Body>>>>::Service as Service<Request<Body>>>::Error:
|
||||||
Into<crate::Error> + Send,
|
Into<crate::Error> + Send,
|
||||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
ResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||||
ResBody::Error: Into<crate::Error>,
|
ResBody::Error: Into<crate::Error>,
|
||||||
{
|
{
|
||||||
let inner = self.server.layer.layer(self.routes);
|
let inner = self.server.layer.layer(self.routes);
|
||||||
@@ -763,7 +763,7 @@ impl<S, ResBody> Service<Request<Body>> for Svc<S>
|
|||||||
where
|
where
|
||||||
S: Service<Request<Body>, Response = Response<ResBody>>,
|
S: Service<Request<Body>, Response = Response<ResBody>>,
|
||||||
S::Error: Into<crate::Error>,
|
S::Error: Into<crate::Error>,
|
||||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
ResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||||
ResBody::Error: Into<crate::Error>,
|
ResBody::Error: Into<crate::Error>,
|
||||||
{
|
{
|
||||||
type Response = Response<BoxHttpBody>;
|
type Response = Response<BoxHttpBody>;
|
||||||
@@ -807,7 +807,7 @@ impl<F, E, ResBody> Future for SvcFuture<F>
|
|||||||
where
|
where
|
||||||
F: Future<Output = Result<Response<ResBody>, E>>,
|
F: Future<Output = Result<Response<ResBody>, E>>,
|
||||||
E: Into<crate::Error>,
|
E: Into<crate::Error>,
|
||||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
ResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||||
ResBody::Error: Into<crate::Error>,
|
ResBody::Error: Into<crate::Error>,
|
||||||
{
|
{
|
||||||
type Output = Result<Response<BoxHttpBody>, crate::Error>;
|
type Output = Result<Response<BoxHttpBody>, crate::Error>;
|
||||||
@@ -817,7 +817,7 @@ where
|
|||||||
let _guard = this.span.enter();
|
let _guard = this.span.enter();
|
||||||
|
|
||||||
let response: Response<ResBody> = ready!(this.inner.poll(cx)).map_err(Into::into)?;
|
let response: Response<ResBody> = ready!(this.inner.poll(cx)).map_err(Into::into)?;
|
||||||
let response = response.map(|body| body.map_err(Into::into).boxed());
|
let response = response.map(|body| body.map_err(Into::into).boxed_unsync());
|
||||||
Poll::Ready(Ok(response))
|
Poll::Ready(Ok(response))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -842,7 +842,7 @@ where
|
|||||||
S: Service<Request<Body>, Response = Response<ResBody>> + Clone + Send + 'static,
|
S: Service<Request<Body>, Response = Response<ResBody>> + Clone + Send + 'static,
|
||||||
S::Future: Send + 'static,
|
S::Future: Send + 'static,
|
||||||
S::Error: Into<crate::Error> + Send,
|
S::Error: Into<crate::Error> + Send,
|
||||||
ResBody: http_body::Body<Data = Bytes> + Send + Sync + 'static,
|
ResBody: http_body::Body<Data = Bytes> + Send + 'static,
|
||||||
ResBody::Error: Into<crate::Error>,
|
ResBody::Error: Into<crate::Error>,
|
||||||
{
|
{
|
||||||
type Response = BoxService;
|
type Response = BoxService;
|
||||||
|
|||||||
Reference in New Issue
Block a user