fix(tonic): Remove Sync requirement for streams (#804)
This commit is contained in:
+2
-2
@@ -55,7 +55,7 @@ http = "0.2"
|
||||
tracing = "0.1"
|
||||
|
||||
async-stream = "0.3"
|
||||
http-body = "0.4.2"
|
||||
http-body = "0.4.4"
|
||||
percent-encoding = "2.1"
|
||||
pin-project = "1.0"
|
||||
tokio-util = {version = "0.6", features = ["codec"]}
|
||||
@@ -71,7 +71,7 @@ async-trait = {version = "0.1.13", optional = true}
|
||||
|
||||
# transport
|
||||
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}
|
||||
tokio = {version = "1.0.1", features = ["net"], optional = true}
|
||||
tokio-stream = "0.1"
|
||||
|
||||
+4
-2
@@ -3,11 +3,13 @@
|
||||
use http_body::Body;
|
||||
|
||||
/// 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
|
||||
// `#[cfg(feature = "codegen")]`.
|
||||
/// Create an empty `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>
|
||||
where
|
||||
T: GrpcService<BoxBody>,
|
||||
T::ResponseBody: Body + Send + Sync + 'static,
|
||||
T::ResponseBody: Body + Send + 'static,
|
||||
<T::ResponseBody as Body>::Error: Into<crate::Error>,
|
||||
C: Codec<Encode = M1, Decode = M2>,
|
||||
M1: Send + Sync + 'static,
|
||||
@@ -169,9 +169,9 @@ impl<T> Grpc<T> {
|
||||
) -> Result<Response<M2>, Status>
|
||||
where
|
||||
T: GrpcService<BoxBody>,
|
||||
T::ResponseBody: Body + Send + Sync + 'static,
|
||||
T::ResponseBody: Body + Send + 'static,
|
||||
<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>,
|
||||
M1: Send + Sync + 'static,
|
||||
M2: Send + Sync + 'static,
|
||||
@@ -206,7 +206,7 @@ impl<T> Grpc<T> {
|
||||
) -> Result<Response<Streaming<M2>>, Status>
|
||||
where
|
||||
T: GrpcService<BoxBody>,
|
||||
T::ResponseBody: Body + Send + Sync + 'static,
|
||||
T::ResponseBody: Body + Send + 'static,
|
||||
<T::ResponseBody as Body>::Error: Into<crate::Error>,
|
||||
C: Codec<Encode = M1, Decode = M2>,
|
||||
M1: Send + Sync + 'static,
|
||||
@@ -225,9 +225,9 @@ impl<T> Grpc<T> {
|
||||
) -> Result<Response<Streaming<M2>>, Status>
|
||||
where
|
||||
T: GrpcService<BoxBody>,
|
||||
T::ResponseBody: Body + Send + Sync + 'static,
|
||||
T::ResponseBody: Body + Send + 'static,
|
||||
<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>,
|
||||
M1: 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
|
||||
/// to fetch the message stream and trailing metadata
|
||||
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,
|
||||
state: State,
|
||||
direction: Direction,
|
||||
@@ -56,9 +56,9 @@ impl<T> Streaming<T> {
|
||||
#[cfg(feature = "compression")] encoding: Option<CompressionEncoding>,
|
||||
) -> Self
|
||||
where
|
||||
B: Body + Send + Sync + 'static,
|
||||
B: Body + Send + 'static,
|
||||
B::Error: Into<crate::Error>,
|
||||
D: Decoder<Item = T, Error = Status> + Send + Sync + 'static,
|
||||
D: Decoder<Item = T, Error = Status> + Send + 'static,
|
||||
{
|
||||
Self::new(
|
||||
decoder,
|
||||
@@ -71,9 +71,9 @@ impl<T> Streaming<T> {
|
||||
|
||||
pub(crate) fn new_empty<B, D>(decoder: D, body: B) -> Self
|
||||
where
|
||||
B: Body + Send + Sync + 'static,
|
||||
B: Body + Send + 'static,
|
||||
B::Error: Into<crate::Error>,
|
||||
D: Decoder<Item = T, Error = Status> + Send + Sync + 'static,
|
||||
D: Decoder<Item = T, Error = Status> + Send + 'static,
|
||||
{
|
||||
Self::new(
|
||||
decoder,
|
||||
@@ -91,9 +91,9 @@ impl<T> Streaming<T> {
|
||||
#[cfg(feature = "compression")] encoding: Option<CompressionEncoding>,
|
||||
) -> Self
|
||||
where
|
||||
B: Body + Send + Sync + 'static,
|
||||
B: Body + Send + 'static,
|
||||
B::Error: Into<crate::Error>,
|
||||
D: Decoder<Item = T, Error = Status> + Send + Sync + 'static,
|
||||
D: Decoder<Item = T, Error = Status> + Send + 'static,
|
||||
{
|
||||
Self::new(
|
||||
decoder,
|
||||
@@ -111,16 +111,16 @@ impl<T> Streaming<T> {
|
||||
#[cfg(feature = "compression")] encoding: Option<CompressionEncoding>,
|
||||
) -> Self
|
||||
where
|
||||
B: Body + Send + Sync + 'static,
|
||||
B: Body + Send + 'static,
|
||||
B::Error: Into<crate::Error>,
|
||||
D: Decoder<Item = T, Error = Status> + Send + Sync + 'static,
|
||||
D: Decoder<Item = T, Error = Status> + Send + 'static,
|
||||
{
|
||||
Self {
|
||||
decoder: Box::new(decoder),
|
||||
body: body
|
||||
.map_data(|mut buf| buf.copy_to_bytes(buf.remaining()))
|
||||
.map_err(|err| Status::map_error(err.into()))
|
||||
.boxed(),
|
||||
.boxed_unsync(),
|
||||
state: State::ReadHeader,
|
||||
direction,
|
||||
buf: BytesMut::with_capacity(BUFFER_SIZE),
|
||||
@@ -140,7 +140,7 @@ impl<T> Streaming<T> {
|
||||
/// # use std::fmt::Debug;
|
||||
/// # async fn next_message_ex<T, D>(mut request: Streaming<T>) -> Result<(), Status>
|
||||
/// # 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? {
|
||||
/// println!("{:?}", next_message);
|
||||
@@ -378,4 +378,4 @@ impl<T> fmt::Debug for Streaming<T> {
|
||||
}
|
||||
|
||||
#[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,
|
||||
) -> EncodeBody<impl Stream<Item = Result<Bytes, Status>>>
|
||||
where
|
||||
T: Encoder<Error = Status> + Send + Sync + 'static,
|
||||
T::Item: Send + Sync,
|
||||
U: Stream<Item = Result<T::Item, Status>> + Send + Sync + 'static,
|
||||
T: Encoder<Error = Status>,
|
||||
U: Stream<Item = Result<T::Item, Status>>,
|
||||
{
|
||||
let stream = encode(
|
||||
encoder,
|
||||
@@ -45,9 +44,8 @@ pub(crate) fn encode_client<T, U>(
|
||||
#[cfg(feature = "compression")] compression_encoding: Option<CompressionEncoding>,
|
||||
) -> EncodeBody<impl Stream<Item = Result<Bytes, Status>>>
|
||||
where
|
||||
T: Encoder<Error = Status> + Send + Sync + 'static,
|
||||
T::Item: Send + Sync,
|
||||
U: Stream<Item = T::Item> + Send + Sync + 'static,
|
||||
T: Encoder<Error = Status>,
|
||||
U: Stream<Item = T::Item>,
|
||||
{
|
||||
let stream = encode(
|
||||
encoder,
|
||||
@@ -157,7 +155,7 @@ pub(crate) struct EncodeBody<S> {
|
||||
|
||||
impl<S> EncodeBody<S>
|
||||
where
|
||||
S: Stream<Item = Result<Bytes, Status>> + Send + Sync + 'static,
|
||||
S: Stream<Item = Result<Bytes, Status>>,
|
||||
{
|
||||
pub(crate) fn new_client(inner: S) -> Self {
|
||||
Self {
|
||||
|
||||
@@ -40,9 +40,9 @@ pub trait Codec: Default {
|
||||
type Decode: Send + 'static;
|
||||
|
||||
/// 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.
|
||||
type Decoder: Decoder<Item = Self::Decode, Error = Status> + Send + Sync + 'static;
|
||||
type Decoder: Decoder<Item = Self::Decode, Error = Status> + Send + 'static;
|
||||
|
||||
/// Fetch the encoder.
|
||||
fn encoder(&mut self) -> Self::Encoder;
|
||||
|
||||
@@ -35,5 +35,7 @@ impl std::fmt::Display for Never {
|
||||
impl std::error::Error for Never {}
|
||||
|
||||
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 {
|
||||
/// 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
|
||||
type Message;
|
||||
@@ -357,7 +357,7 @@ impl<T> IntoRequest<T> for Request<T> {
|
||||
|
||||
impl<T> IntoStreamingRequest for T
|
||||
where
|
||||
T: Stream + Send + Sync + 'static,
|
||||
T: Stream + Send + 'static,
|
||||
{
|
||||
type Stream = T;
|
||||
type Message = T::Item;
|
||||
@@ -369,7 +369,7 @@ where
|
||||
|
||||
impl<T> IntoStreamingRequest for Request<T>
|
||||
where
|
||||
T: Stream + Send + Sync + 'static,
|
||||
T: Stream + Send + 'static,
|
||||
{
|
||||
type Stream = T;
|
||||
type Message = T::Item;
|
||||
|
||||
@@ -44,7 +44,6 @@ pub struct Grpc<T> {
|
||||
impl<T> Grpc<T>
|
||||
where
|
||||
T: Codec,
|
||||
T::Encode: Sync,
|
||||
{
|
||||
/// Creates a new gRPC server with the provided [`Codec`].
|
||||
pub fn new(codec: T) -> Self {
|
||||
@@ -173,7 +172,7 @@ where
|
||||
) -> http::Response<BoxBody>
|
||||
where
|
||||
S: UnaryService<T::Decode, Response = T::Encode>,
|
||||
B: Body + Send + Sync + 'static,
|
||||
B: Body + Send + 'static,
|
||||
B::Error: Into<crate::Error> + Send,
|
||||
{
|
||||
#[cfg(feature = "compression")]
|
||||
@@ -221,8 +220,8 @@ where
|
||||
) -> http::Response<BoxBody>
|
||||
where
|
||||
S: ServerStreamingService<T::Decode, Response = T::Encode>,
|
||||
S::ResponseStream: Send + Sync + 'static,
|
||||
B: Body + Send + Sync + 'static,
|
||||
S::ResponseStream: Send + 'static,
|
||||
B: Body + Send + 'static,
|
||||
B::Error: Into<crate::Error> + Send,
|
||||
{
|
||||
#[cfg(feature = "compression")]
|
||||
@@ -265,7 +264,7 @@ where
|
||||
) -> http::Response<BoxBody>
|
||||
where
|
||||
S: ClientStreamingService<T::Decode, Response = T::Encode>,
|
||||
B: Body + Send + Sync + 'static,
|
||||
B: Body + Send + 'static,
|
||||
B::Error: Into<crate::Error> + Send + 'static,
|
||||
{
|
||||
#[cfg(feature = "compression")]
|
||||
@@ -301,8 +300,8 @@ where
|
||||
) -> http::Response<BoxBody>
|
||||
where
|
||||
S: StreamingService<T::Decode, Response = T::Encode> + Send,
|
||||
S::ResponseStream: Send + Sync + 'static,
|
||||
B: Body + Send + Sync + 'static,
|
||||
S::ResponseStream: Send + 'static,
|
||||
B: Body + Send + 'static,
|
||||
B::Error: Into<crate::Error> + Send,
|
||||
{
|
||||
#[cfg(feature = "compression")]
|
||||
@@ -329,7 +328,7 @@ where
|
||||
request: http::Request<B>,
|
||||
) -> Result<Request<T::Decode>, Status>
|
||||
where
|
||||
B: Body + Send + Sync + 'static,
|
||||
B: Body + Send + 'static,
|
||||
B::Error: Into<crate::Error> + Send,
|
||||
{
|
||||
#[cfg(feature = "compression")]
|
||||
@@ -365,7 +364,7 @@ where
|
||||
request: http::Request<B>,
|
||||
) -> Result<Request<Streaming<T::Decode>>, Status>
|
||||
where
|
||||
B: Body + Send + Sync + 'static,
|
||||
B: Body + Send + 'static,
|
||||
B::Error: Into<crate::Error> + Send,
|
||||
{
|
||||
#[cfg(feature = "compression")]
|
||||
@@ -388,7 +387,7 @@ where
|
||||
#[cfg(feature = "compression")] compression_override: SingleMessageCompressionOverride,
|
||||
) -> http::Response<BoxBody>
|
||||
where
|
||||
B: TryStream<Ok = T::Encode, Error = Status> + Send + Sync + 'static,
|
||||
B: TryStream<Ok = T::Encode, Error = Status> + Send + 'static,
|
||||
{
|
||||
let response = match response {
|
||||
Ok(r) => r,
|
||||
|
||||
@@ -54,7 +54,7 @@ use tower::{
|
||||
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 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,
|
||||
IE: Into<crate::Error>,
|
||||
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>,
|
||||
{
|
||||
let trace_interceptor = self.trace_interceptor.clone();
|
||||
@@ -627,7 +627,7 @@ where
|
||||
Send + 'static,
|
||||
<<L as Layer<Routes<A, B, Request<Body>>>>::Service as Service<Request<Body>>>::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>,
|
||||
{
|
||||
let incoming = TcpIncoming::new(addr, self.server.tcp_nodelay, self.server.tcp_keepalive)
|
||||
@@ -659,7 +659,7 @@ where
|
||||
Send + 'static,
|
||||
<<L as Layer<Routes<A, B, Request<Body>>>>::Service as Service<Request<Body>>>::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>,
|
||||
{
|
||||
let incoming = TcpIncoming::new(addr, self.server.tcp_nodelay, self.server.tcp_keepalive)
|
||||
@@ -688,7 +688,7 @@ where
|
||||
Send + 'static,
|
||||
<<L as Layer<Routes<A, B, Request<Body>>>>::Service as Service<Request<Body>>>::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>,
|
||||
{
|
||||
self.server
|
||||
@@ -723,7 +723,7 @@ where
|
||||
Send + 'static,
|
||||
<<L as Layer<Routes<A, B, Request<Body>>>>::Service as Service<Request<Body>>>::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>,
|
||||
{
|
||||
self.server
|
||||
@@ -740,7 +740,7 @@ where
|
||||
Send + 'static,
|
||||
<<L as Layer<Routes<A, B, Request<Body>>>>::Service as Service<Request<Body>>>::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>,
|
||||
{
|
||||
let inner = self.server.layer.layer(self.routes);
|
||||
@@ -763,7 +763,7 @@ impl<S, ResBody> Service<Request<Body>> for Svc<S>
|
||||
where
|
||||
S: Service<Request<Body>, Response = Response<ResBody>>,
|
||||
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>,
|
||||
{
|
||||
type Response = Response<BoxHttpBody>;
|
||||
@@ -807,7 +807,7 @@ impl<F, E, ResBody> Future for SvcFuture<F>
|
||||
where
|
||||
F: Future<Output = Result<Response<ResBody>, E>>,
|
||||
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>,
|
||||
{
|
||||
type Output = Result<Response<BoxHttpBody>, crate::Error>;
|
||||
@@ -817,7 +817,7 @@ where
|
||||
let _guard = this.span.enter();
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
@@ -842,7 +842,7 @@ where
|
||||
S: Service<Request<Body>, Response = Response<ResBody>> + Clone + Send + 'static,
|
||||
S::Future: Send + 'static,
|
||||
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>,
|
||||
{
|
||||
type Response = BoxService;
|
||||
|
||||
Reference in New Issue
Block a user