From 8317a8c797321fbaa03dbc4a48ed9bc7e4190fb6 Mon Sep 17 00:00:00 2001 From: Lucio Franco Date: Mon, 21 Oct 2019 15:04:20 -0400 Subject: [PATCH 1/3] fix(codec): Enforce encoders/decoders are `Sync` Closes #81 --- tonic/src/codec/decode.rs | 10 +++++----- tonic/src/codec/mod.rs | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tonic/src/codec/decode.rs b/tonic/src/codec/decode.rs index 413afdb45..ba3686818 100644 --- a/tonic/src/codec/decode.rs +++ b/tonic/src/codec/decode.rs @@ -19,7 +19,7 @@ const BUFFER_SIZE: usize = 8 * 1024; /// This will wrap some inner [`Body`] and [`Decoder`] and provide an interface /// to fetch the message stream and trailing metadata pub struct Streaming { - decoder: Box + Send + 'static>, + decoder: Box + Sync + Send + 'static>, body: BoxBody, state: State, direction: Direction, @@ -48,7 +48,7 @@ impl Streaming { B: Body + Send + 'static, B::Data: Into, B::Error: Into, - D: Decoder + Send + 'static, + D: Decoder + Sync + Send + 'static, { Self::new(decoder, body, Direction::Response(status_code)) } @@ -58,7 +58,7 @@ impl Streaming { B: Body + Send + 'static, B::Data: Into, B::Error: Into, - D: Decoder + Send + 'static, + D: Decoder + Sync + Send + 'static, { Self::new(decoder, body, Direction::EmptyResponse) } @@ -68,7 +68,7 @@ impl Streaming { B: Body + Send + 'static, B::Data: Into, B::Error: Into, - D: Decoder + Send + 'static, + D: Decoder + Sync + Send + 'static, { Self::new(decoder, body, Direction::Request) } @@ -78,7 +78,7 @@ impl Streaming { B: Body + Send + 'static, B::Data: Into, B::Error: Into, - D: Decoder + Send + 'static, + D: Decoder + Sync + Send + 'static, { Self { decoder: Box::new(decoder), diff --git a/tonic/src/codec/mod.rs b/tonic/src/codec/mod.rs index c32c729af..3f345fdfd 100644 --- a/tonic/src/codec/mod.rs +++ b/tonic/src/codec/mod.rs @@ -28,9 +28,9 @@ pub trait Codec { type Decode: Send + 'static; /// The encoder that can encode a message. - type Encoder: Encoder + Send + 'static; + type Encoder: Encoder + Sync + Send + 'static; /// The encoder that can decode a message. - type Decoder: Decoder + Send + 'static; + type Decoder: Decoder + Sync + Send + 'static; /// The content type of this codec. /// From f17376d637ff75172d6f069bcf8d47f750729dc2 Mon Sep 17 00:00:00 2001 From: Lucio Franco Date: Mon, 21 Oct 2019 20:00:29 -0400 Subject: [PATCH 2/3] add more sync bounds --- tonic-build/src/client.rs | 4 ++-- tonic-build/src/server.rs | 4 ++-- tonic-examples/src/routeguide/server.rs | 5 +++-- tonic-interop/src/server.rs | 5 +++-- tonic/Cargo.toml | 3 +++ tonic/src/body.rs | 10 +++++----- tonic/src/client/grpc.rs | 20 ++++++++++---------- tonic/src/codec/decode.rs | 11 +++++++---- tonic/src/codec/encode.rs | 12 +++++++----- tonic/src/server/grpc.rs | 19 ++++++++++--------- 10 files changed, 52 insertions(+), 41 deletions(-) diff --git a/tonic-build/src/client.rs b/tonic-build/src/client.rs index a5dec9d1f..3c01efcd3 100644 --- a/tonic-build/src/client.rs +++ b/tonic-build/src/client.rs @@ -133,7 +133,7 @@ fn generate_client_streaming(method: &Method, proto: &str, path: String) -> Toke quote! { pub async fn #ident(&mut self, request: tonic::Request) -> Result, tonic::Status> - where S: Stream + Send + 'static, + where S: Stream + Sync + Send + 'static, { self.ready().await?; let codec = tonic::codec::ProstCodec::new(); @@ -151,7 +151,7 @@ fn generate_streaming(method: &Method, proto: &str, path: String) -> TokenStream quote! { pub async fn #ident(&mut self, request: tonic::Request) -> Result>, tonic::Status> - where S: Stream + Send + 'static, + where S: Stream + Sync + Send + 'static, { self.ready().await?; let codec = tonic::codec::ProstCodec::new(); diff --git a/tonic-build/src/server.rs b/tonic-build/src/server.rs index d19f45a7d..155c7f7d8 100644 --- a/tonic-build/src/server.rs +++ b/tonic-build/src/server.rs @@ -146,7 +146,7 @@ fn generate_trait_methods(service: &Service, proto_path: &str) -> TokenStream { quote! { #stream_doc - type #stream: Stream> + Send + 'static; + type #stream: Stream> + Sync + Send + 'static; #method_doc async fn #name(&self, request: tonic::Request<#req_message>) @@ -164,7 +164,7 @@ fn generate_trait_methods(service: &Service, proto_path: &str) -> TokenStream { quote! { #stream_doc - type #stream: Stream> + Send + 'static; + type #stream: Stream> + Sync + Send + 'static; #method_doc async fn #name(&self, request: tonic::Request>) diff --git a/tonic-examples/src/routeguide/server.rs b/tonic-examples/src/routeguide/server.rs index 5732c52cc..99efcb7ec 100644 --- a/tonic-examples/src/routeguide/server.rs +++ b/tonic-examples/src/routeguide/server.rs @@ -108,7 +108,8 @@ impl server::RouteGuide for RouteGuide { Ok(Response::new(summary)) } - type RouteChatStream = Pin> + Send + 'static>>; + type RouteChatStream = + Pin> + Sync + Send + 'static>>; async fn route_chat( &self, @@ -138,7 +139,7 @@ impl server::RouteGuide for RouteGuide { Ok(Response::new(Box::pin(output) as Pin< - Box> + Send + 'static>, + Box> + Sync + Send + 'static>, >)) } } diff --git a/tonic-interop/src/server.rs b/tonic-interop/src/server.rs index a0d9c7360..eda185da8 100644 --- a/tonic-interop/src/server.rs +++ b/tonic-interop/src/server.rs @@ -12,8 +12,9 @@ pub struct TestService; type Result = std::result::Result, Status>; type Streaming = Request>; -type Stream = - Pin> + Send + 'static>>; +type Stream = Pin< + Box> + Sync + Send + 'static>, +>; #[tonic::async_trait] impl pb::server::TestService for TestService { diff --git a/tonic/Cargo.toml b/tonic/Cargo.toml index 3cfe74d0f..25cd20342 100644 --- a/tonic/Cargo.toml +++ b/tonic/Cargo.toml @@ -75,6 +75,9 @@ openssl1 = { package = "openssl", version = "0.10", optional = true } # rustls tokio-rustls = { version = "=0.12.0-alpha.4", optional = true } +[dev-dependencies] +static_assertions = "1.0" + [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] diff --git a/tonic/src/body.rs b/tonic/src/body.rs index 41930edab..9003619e5 100644 --- a/tonic/src/body.rs +++ b/tonic/src/body.rs @@ -15,7 +15,7 @@ use std::{ pub(crate) type BytesBuf = ::Buf; /// A trait alias for [`http_body::Body`]. -pub trait Body: sealed::Sealed { +pub trait Body: sealed::Sealed + Sync + Send { /// The body data type. type Data: Buf; /// The errors produced from the body. @@ -45,7 +45,7 @@ pub trait Body: sealed::Sealed { impl Body for T where - T: HttpBody, + T: HttpBody + Send + Sync + 'static, T::Error: Into, { type Data = T::Data; @@ -83,7 +83,7 @@ mod sealed { /// A type erased http body. pub struct BoxBody { - inner: Pin + Send + 'static>>, + inner: Pin + Sync + Send + 'static>>, } struct MapBody(B); @@ -92,7 +92,7 @@ impl BoxBody { /// Create a new `BoxBody` mapping item and error to the default types. pub fn new(inner: B) -> Self where - B: Body + Send + 'static, + B: Body + Sync + Send + 'static, { BoxBody { inner: Box::pin(inner), @@ -102,7 +102,7 @@ impl BoxBody { /// Create a new `BoxBody` mapping item and error to the default types. pub fn map_from(inner: B) -> Self where - B: Body + Send + 'static, + B: Body + Sync + Send + 'static, B::Data: Into, B::Error: Into, { diff --git a/tonic/src/client/grpc.rs b/tonic/src/client/grpc.rs index 95712c50d..07ffac564 100644 --- a/tonic/src/client/grpc.rs +++ b/tonic/src/client/grpc.rs @@ -62,8 +62,8 @@ impl Grpc { ::Error: Into, ::Data: Into, C: Codec, - M1: Send + 'static, - M2: Send + 'static, + M1: Sync + Send + 'static, + M2: Sync + Send + 'static, { let request = request.map(|m| stream::once(future::ready(m))); self.client_streaming(request, path, codec).await @@ -81,10 +81,10 @@ impl Grpc { T::ResponseBody: Body + HttpBody + Send + 'static, ::Error: Into, ::Data: Into, - S: Stream + Send + 'static, + S: Stream + Sync + Send + 'static, C: Codec, - M1: Send + 'static, - M2: Send + 'static, + M1: Sync + Send + 'static, + M2: Sync + Send + 'static, { let (mut parts, body) = self.streaming(request, path, codec).await?.into_parts(); @@ -115,8 +115,8 @@ impl Grpc { ::Error: Into, ::Data: Into, C: Codec, - M1: Send + 'static, - M2: Send + 'static, + M1: Sync + Send + 'static, + M2: Sync + Send + 'static, { let request = request.map(|m| stream::once(future::ready(m))); self.streaming(request, path, codec).await @@ -134,10 +134,10 @@ impl Grpc { T::ResponseBody: Body + HttpBody + Send + 'static, ::Data: Into, ::Error: Into, - S: Stream + Send + 'static, + S: Stream + Sync + Send + 'static, C: Codec, - M1: Send + 'static, - M2: Send + 'static, + M1: Sync + Send + 'static, + M2: Sync + Send + 'static, { let mut parts = Parts::default(); parts.path_and_query = Some(path); diff --git a/tonic/src/codec/decode.rs b/tonic/src/codec/decode.rs index ba3686818..391df1709 100644 --- a/tonic/src/codec/decode.rs +++ b/tonic/src/codec/decode.rs @@ -27,6 +27,9 @@ pub struct Streaming { trailers: Option, } +#[cfg(test)] +static_assertions::assert_impl_all!(Streaming<()>: Send, Sync); + impl Unpin for Streaming {} #[derive(Debug)] @@ -45,7 +48,7 @@ enum Direction { impl Streaming { pub(crate) fn new_response(decoder: D, body: B, status_code: StatusCode) -> Self where - B: Body + Send + 'static, + B: Body + Sync + Send + 'static, B::Data: Into, B::Error: Into, D: Decoder + Sync + Send + 'static, @@ -55,7 +58,7 @@ impl Streaming { pub(crate) fn new_empty(decoder: D, body: B) -> Self where - B: Body + Send + 'static, + B: Body + Sync + Send + 'static, B::Data: Into, B::Error: Into, D: Decoder + Sync + Send + 'static, @@ -65,7 +68,7 @@ impl Streaming { pub(crate) fn new_request(decoder: D, body: B) -> Self where - B: Body + Send + 'static, + B: Body + Sync + Send + 'static, B::Data: Into, B::Error: Into, D: Decoder + Sync + Send + 'static, @@ -75,7 +78,7 @@ impl Streaming { fn new(decoder: D, body: B, direction: Direction) -> Self where - B: Body + Send + 'static, + B: Body + Sync + Send + 'static, B::Data: Into, B::Error: Into, D: Decoder + Sync + Send + 'static, diff --git a/tonic/src/codec/encode.rs b/tonic/src/codec/encode.rs index 7d91b4b94..5a0f94b1d 100644 --- a/tonic/src/codec/encode.rs +++ b/tonic/src/codec/encode.rs @@ -16,8 +16,9 @@ pub(crate) fn encode_server( source: U, ) -> EncodeBody>> where - T: Encoder, - U: Stream>, + T: Encoder + Send + Sync + 'static, + T::Item: Send + Sync, + U: Stream> + Send + Sync + 'static, { let stream = encode(encoder, source).into_stream(); EncodeBody::new_server(stream) @@ -28,8 +29,9 @@ pub(crate) fn encode_client( source: U, ) -> EncodeBody>> where - T: Encoder, - U: Stream, + T: Encoder + Send + Sync + 'static, + T::Item: Send + Sync, + U: Stream + Send + Sync + 'static, { let stream = encode(encoder, source.map(|x| Ok(x))).into_stream(); EncodeBody::new_client(stream) @@ -88,7 +90,7 @@ pub(crate) struct EncodeBody { impl EncodeBody where - S: Stream>, + S: Stream> + Send + Sync + 'static, { pub(crate) fn new_client(inner: S) -> Self { Self { diff --git a/tonic/src/server/grpc.rs b/tonic/src/server/grpc.rs index 3653c79b8..038284b67 100644 --- a/tonic/src/server/grpc.rs +++ b/tonic/src/server/grpc.rs @@ -26,6 +26,7 @@ pub struct Grpc { impl Grpc where T: Codec, + T::Encode: Sync, { /// Creates a new gRPC client with the provided [`Codec`]. pub fn new(codec: T) -> Self { @@ -40,7 +41,7 @@ where ) -> http::Response where S: UnaryService, - B: Body + Send + 'static, + B: Body + Sync + Send + 'static, B::Data: Into + Send, B::Error: Into + Send, { @@ -70,8 +71,8 @@ where ) -> http::Response where S: ServerStreamingService, - S::ResponseStream: Send + 'static, - B: Body + Send + 'static, + S::ResponseStream: Sync + Send + 'static, + B: Body + Sync + Send + 'static, B::Data: Into + Send, B::Error: Into + Send, { @@ -95,7 +96,7 @@ where ) -> http::Response where S: ClientStreamingService, - B: Body + Send + 'static, + B: Body + Sync + Send + 'static, B::Data: Into + Send + 'static, B::Error: Into + Send + 'static, { @@ -115,8 +116,8 @@ where ) -> http::Response where S: StreamingService + Send, - S::ResponseStream: Send + 'static, - B: Body + Send + 'static, + S::ResponseStream: Sync + Send + 'static, + B: Body + Sync + Send + 'static, B::Data: Into + Send, B::Error: Into + Send, { @@ -130,7 +131,7 @@ where request: http::Request, ) -> Result, Status> where - B: Body + Send + 'static, + B: Body + Sync + Send + 'static, B::Data: Into + Send, B::Error: Into + Send, { @@ -158,7 +159,7 @@ where request: http::Request, ) -> Request> where - B: Body + Send + 'static, + B: Body + Sync + Send + 'static, B::Data: Into + Send, B::Error: Into + Send, { @@ -170,7 +171,7 @@ where response: Result, Status>, ) -> http::Response where - B: TryStream + Send + 'static, + B: TryStream + Sync + Send + 'static, { match response { Ok(r) => { From 5105ca68455e4ac42b2d985f9c18d79d1b0c6333 Mon Sep 17 00:00:00 2001 From: Lucio Franco Date: Thu, 24 Oct 2019 10:53:08 -0400 Subject: [PATCH 3/3] Switch order of Send and Sync --- tonic-build/src/client.rs | 4 ++-- tonic-build/src/server.rs | 4 ++-- tonic-examples/src/routeguide/server.rs | 4 ++-- tonic-interop/src/server.rs | 2 +- tonic/Cargo.toml | 6 ++---- tonic/src/body.rs | 8 ++++---- tonic/src/client/grpc.rs | 20 ++++++++++---------- tonic/src/codec/decode.rs | 24 ++++++++++++------------ tonic/src/codec/mod.rs | 4 ++-- tonic/src/server/grpc.rs | 18 +++++++++--------- 10 files changed, 46 insertions(+), 48 deletions(-) diff --git a/tonic-build/src/client.rs b/tonic-build/src/client.rs index 346221aba..edeeb240f 100644 --- a/tonic-build/src/client.rs +++ b/tonic-build/src/client.rs @@ -133,7 +133,7 @@ fn generate_client_streaming(method: &Method, proto: &str, path: String) -> Toke quote! { pub async fn #ident(&mut self, request: tonic::Request) -> Result, tonic::Status> - where S: Stream + Sync + Send + 'static, + where S: Stream + Send + Sync + 'static, { self.ready().await?; let codec = tonic::codec::ProstCodec::new(); @@ -151,7 +151,7 @@ fn generate_streaming(method: &Method, proto: &str, path: String) -> TokenStream quote! { pub async fn #ident(&mut self, request: tonic::Request) -> Result>, tonic::Status> - where S: Stream + Sync + Send + 'static, + where S: Stream + Send + Sync + 'static, { self.ready().await?; let codec = tonic::codec::ProstCodec::new(); diff --git a/tonic-build/src/server.rs b/tonic-build/src/server.rs index 7c03dcc24..9173bff4f 100644 --- a/tonic-build/src/server.rs +++ b/tonic-build/src/server.rs @@ -146,7 +146,7 @@ fn generate_trait_methods(service: &Service, proto_path: &str) -> TokenStream { quote! { #stream_doc - type #stream: Stream> + Sync + Send + 'static; + type #stream: Stream> + Send + Sync + 'static; #method_doc async fn #name(&self, request: tonic::Request<#req_message>) @@ -164,7 +164,7 @@ fn generate_trait_methods(service: &Service, proto_path: &str) -> TokenStream { quote! { #stream_doc - type #stream: Stream> + Sync + Send + 'static; + type #stream: Stream> + Send + Sync + 'static; #method_doc async fn #name(&self, request: tonic::Request>) diff --git a/tonic-examples/src/routeguide/server.rs b/tonic-examples/src/routeguide/server.rs index 99efcb7ec..f56064a51 100644 --- a/tonic-examples/src/routeguide/server.rs +++ b/tonic-examples/src/routeguide/server.rs @@ -109,7 +109,7 @@ impl server::RouteGuide for RouteGuide { } type RouteChatStream = - Pin> + Sync + Send + 'static>>; + Pin> + Send + Sync + 'static>>; async fn route_chat( &self, @@ -139,7 +139,7 @@ impl server::RouteGuide for RouteGuide { Ok(Response::new(Box::pin(output) as Pin< - Box> + Sync + Send + 'static>, + Box> + Send + Sync + 'static>, >)) } } diff --git a/tonic-interop/src/server.rs b/tonic-interop/src/server.rs index eda185da8..738441501 100644 --- a/tonic-interop/src/server.rs +++ b/tonic-interop/src/server.rs @@ -13,7 +13,7 @@ pub struct TestService; type Result = std::result::Result, Status>; type Streaming = Request>; type Stream = Pin< - Box> + Sync + Send + 'static>, + Box> + Send + Sync + 'static>, >; #[tonic::async_trait] diff --git a/tonic/Cargo.toml b/tonic/Cargo.toml index d3a82ee23..662ef9fda 100644 --- a/tonic/Cargo.toml +++ b/tonic/Cargo.toml @@ -41,10 +41,6 @@ tls = [] name = "bench_main" harness = false -[dev-dependencies] -rand = "0.7.2" -criterion = "0.3" - [dependencies] bytes = "0.4" futures-core-preview = "=0.3.0-alpha.19" @@ -85,6 +81,8 @@ tokio-rustls = { version = "=0.12.0-alpha.4", optional = true } [dev-dependencies] static_assertions = "1.0" +rand = "0.7.2" +criterion = "0.3" [package.metadata.docs.rs] all-features = true diff --git a/tonic/src/body.rs b/tonic/src/body.rs index 9003619e5..ee0a662ad 100644 --- a/tonic/src/body.rs +++ b/tonic/src/body.rs @@ -15,7 +15,7 @@ use std::{ pub(crate) type BytesBuf = ::Buf; /// A trait alias for [`http_body::Body`]. -pub trait Body: sealed::Sealed + Sync + Send { +pub trait Body: sealed::Sealed + Send + Sync { /// The body data type. type Data: Buf; /// The errors produced from the body. @@ -83,7 +83,7 @@ mod sealed { /// A type erased http body. pub struct BoxBody { - inner: Pin + Sync + Send + 'static>>, + inner: Pin + Send + Sync + 'static>>, } struct MapBody(B); @@ -92,7 +92,7 @@ impl BoxBody { /// Create a new `BoxBody` mapping item and error to the default types. pub fn new(inner: B) -> Self where - B: Body + Sync + Send + 'static, + B: Body + Send + Sync + 'static, { BoxBody { inner: Box::pin(inner), @@ -102,7 +102,7 @@ impl BoxBody { /// Create a new `BoxBody` mapping item and error to the default types. pub fn map_from(inner: B) -> Self where - B: Body + Sync + Send + 'static, + B: Body + Send + Sync + 'static, B::Data: Into, B::Error: Into, { diff --git a/tonic/src/client/grpc.rs b/tonic/src/client/grpc.rs index 07ffac564..9301f713f 100644 --- a/tonic/src/client/grpc.rs +++ b/tonic/src/client/grpc.rs @@ -62,8 +62,8 @@ impl Grpc { ::Error: Into, ::Data: Into, C: Codec, - M1: Sync + Send + 'static, - M2: Sync + Send + 'static, + M1: Send + Sync + 'static, + M2: Send + Sync + 'static, { let request = request.map(|m| stream::once(future::ready(m))); self.client_streaming(request, path, codec).await @@ -81,10 +81,10 @@ impl Grpc { T::ResponseBody: Body + HttpBody + Send + 'static, ::Error: Into, ::Data: Into, - S: Stream + Sync + Send + 'static, + S: Stream + Send + Sync + 'static, C: Codec, - M1: Sync + Send + 'static, - M2: Sync + Send + 'static, + M1: Send + Sync + 'static, + M2: Send + Sync + 'static, { let (mut parts, body) = self.streaming(request, path, codec).await?.into_parts(); @@ -115,8 +115,8 @@ impl Grpc { ::Error: Into, ::Data: Into, C: Codec, - M1: Sync + Send + 'static, - M2: Sync + Send + 'static, + M1: Send + Sync + 'static, + M2: Send + Sync + 'static, { let request = request.map(|m| stream::once(future::ready(m))); self.streaming(request, path, codec).await @@ -134,10 +134,10 @@ impl Grpc { T::ResponseBody: Body + HttpBody + Send + 'static, ::Data: Into, ::Error: Into, - S: Stream + Sync + Send + 'static, + S: Stream + Send + Sync + 'static, C: Codec, - M1: Sync + Send + 'static, - M2: Sync + Send + 'static, + M1: Send + Sync + 'static, + M2: Send + Sync + 'static, { let mut parts = Parts::default(); parts.path_and_query = Some(path); diff --git a/tonic/src/codec/decode.rs b/tonic/src/codec/decode.rs index cd0d9b664..fba1ba281 100644 --- a/tonic/src/codec/decode.rs +++ b/tonic/src/codec/decode.rs @@ -19,7 +19,7 @@ const BUFFER_SIZE: usize = 8 * 1024; /// This will wrap some inner [`Body`] and [`Decoder`] and provide an interface /// to fetch the message stream and trailing metadata pub struct Streaming { - decoder: Box + Sync + Send + 'static>, + decoder: Box + Send + Sync + 'static>, body: BoxBody, state: State, direction: Direction, @@ -27,9 +27,6 @@ pub struct Streaming { trailers: Option, } -#[cfg(test)] -static_assertions::assert_impl_all!(Streaming<()>: Send, Sync); - impl Unpin for Streaming {} #[derive(Debug)] @@ -48,40 +45,40 @@ enum Direction { impl Streaming { pub(crate) fn new_response(decoder: D, body: B, status_code: StatusCode) -> Self where - B: Body + Sync + Send + 'static, + B: Body + Send + Sync + 'static, B::Data: Into, B::Error: Into, - D: Decoder + Sync + Send + 'static, + D: Decoder + Send + Sync + 'static, { Self::new(decoder, body, Direction::Response(status_code)) } pub(crate) fn new_empty(decoder: D, body: B) -> Self where - B: Body + Sync + Send + 'static, + B: Body + Send + Sync + 'static, B::Data: Into, B::Error: Into, - D: Decoder + Sync + Send + 'static, + D: Decoder + Send + Sync + 'static, { Self::new(decoder, body, Direction::EmptyResponse) } pub(crate) fn new_request(decoder: D, body: B) -> Self where - B: Body + Sync + Send + 'static, + B: Body + Send + Sync + 'static, B::Data: Into, B::Error: Into, - D: Decoder + Sync + Send + 'static, + D: Decoder + Send + Sync + 'static, { Self::new(decoder, body, Direction::Request) } fn new(decoder: D, body: B, direction: Direction) -> Self where - B: Body + Sync + Send + 'static, + B: Body + Send + Sync + 'static, B::Data: Into, B::Error: Into, - D: Decoder + Sync + Send + 'static, + D: Decoder + Send + Sync + 'static, { Self { decoder: Box::new(decoder), @@ -294,3 +291,6 @@ impl fmt::Debug for Streaming { f.debug_struct("Streaming").finish() } } + +#[cfg(test)] +static_assertions::assert_impl_all!(Streaming<()>: Send, Sync); diff --git a/tonic/src/codec/mod.rs b/tonic/src/codec/mod.rs index 3f345fdfd..d316a11a1 100644 --- a/tonic/src/codec/mod.rs +++ b/tonic/src/codec/mod.rs @@ -28,9 +28,9 @@ pub trait Codec { type Decode: Send + 'static; /// The encoder that can encode a message. - type Encoder: Encoder + Sync + Send + 'static; + type Encoder: Encoder + Send + Sync + 'static; /// The encoder that can decode a message. - type Decoder: Decoder + Sync + Send + 'static; + type Decoder: Decoder + Send + Sync + 'static; /// The content type of this codec. /// diff --git a/tonic/src/server/grpc.rs b/tonic/src/server/grpc.rs index 038284b67..5f9cabf91 100644 --- a/tonic/src/server/grpc.rs +++ b/tonic/src/server/grpc.rs @@ -41,7 +41,7 @@ where ) -> http::Response where S: UnaryService, - B: Body + Sync + Send + 'static, + B: Body + Send + Sync + 'static, B::Data: Into + Send, B::Error: Into + Send, { @@ -71,8 +71,8 @@ where ) -> http::Response where S: ServerStreamingService, - S::ResponseStream: Sync + Send + 'static, - B: Body + Sync + Send + 'static, + S::ResponseStream: Send + Sync + 'static, + B: Body + Send + Sync + 'static, B::Data: Into + Send, B::Error: Into + Send, { @@ -96,7 +96,7 @@ where ) -> http::Response where S: ClientStreamingService, - B: Body + Sync + Send + 'static, + B: Body + Send + Sync + 'static, B::Data: Into + Send + 'static, B::Error: Into + Send + 'static, { @@ -116,8 +116,8 @@ where ) -> http::Response where S: StreamingService + Send, - S::ResponseStream: Sync + Send + 'static, - B: Body + Sync + Send + 'static, + S::ResponseStream: Send + Sync + 'static, + B: Body + Send + Sync + 'static, B::Data: Into + Send, B::Error: Into + Send, { @@ -131,7 +131,7 @@ where request: http::Request, ) -> Result, Status> where - B: Body + Sync + Send + 'static, + B: Body + Send + Sync + 'static, B::Data: Into + Send, B::Error: Into + Send, { @@ -159,7 +159,7 @@ where request: http::Request, ) -> Request> where - B: Body + Sync + Send + 'static, + B: Body + Send + Sync + 'static, B::Data: Into + Send, B::Error: Into + Send, { @@ -171,7 +171,7 @@ where response: Result, Status>, ) -> http::Response where - B: TryStream + Sync + Send + 'static, + B: TryStream + Send + Sync + 'static, { match response { Ok(r) => {