Skip to content

Commit 3c900eb

Browse files
authored
Clean up EncodeBody API (#1924)
* tonic: remove unnecessary bounds in codec::encode * tonic: reduce unnecessary visibility for EncodedBytes * tonic: use EncodedBytes directly in EncodeBody * tonic: handle fuse() inside EncodedBytes * tonic: fold encode_server() into EncodeBody::new_server() * tonic: move mapping responsibility to caller * tonic: fold encode_client() into EncodeBody::new_client()
1 parent e6782fe commit 3c900eb

File tree

6 files changed

+57
-80
lines changed

6 files changed

+57
-80
lines changed

tonic/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ percent-encoding = "2.1"
6969
pin-project = "1.0.11"
7070
tower-layer = "0.3"
7171
tower-service = "0.3"
72-
tokio-stream = {version = "0.1", default-features = false}
72+
tokio-stream = {version = "0.1.16", default-features = false}
7373

7474
# prost
7575
prost = {version = "0.13", default-features = false, features = ["std"], optional = true}

tonic/src/client/grpc.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use crate::codec::compression::{CompressionEncoding, EnabledCompressionEncodings};
2+
use crate::codec::EncodeBody;
23
use crate::metadata::GRPC_CONTENT_TYPE;
34
use crate::{
45
body::BoxBody,
56
client::GrpcService,
6-
codec::{encode_client, Codec, Decoder, Streaming},
7+
codec::{Codec, Decoder, Streaming},
78
request::SanitizeHeaders,
89
Code, Request, Response, Status,
910
};
@@ -295,9 +296,9 @@ impl<T> Grpc<T> {
295296
{
296297
let request = request
297298
.map(|s| {
298-
encode_client(
299+
EncodeBody::new_client(
299300
codec.encoder(),
300-
s,
301+
s.map(Ok),
301302
self.config.send_compression_encodings,
302303
self.config.max_encoding_message_size,
303304
)

tonic/src/codec/encode.rs

Lines changed: 42 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -11,53 +11,7 @@ use std::{
1111
pin::Pin,
1212
task::{ready, Context, Poll},
1313
};
14-
use tokio_stream::{Stream, StreamExt};
15-
16-
/// Turns a stream of grpc results (message or error status) into [EncodeBody] which is used by grpc
17-
/// servers for turning the messages into http frames for sending over the network.
18-
pub fn encode_server<T, U>(
19-
encoder: T,
20-
source: U,
21-
compression_encoding: Option<CompressionEncoding>,
22-
compression_override: SingleMessageCompressionOverride,
23-
max_message_size: Option<usize>,
24-
) -> EncodeBody<impl Stream<Item = Result<Bytes, Status>>>
25-
where
26-
T: Encoder<Error = Status>,
27-
U: Stream<Item = Result<T::Item, Status>>,
28-
{
29-
let stream = EncodedBytes::new(
30-
encoder,
31-
source.fuse(),
32-
compression_encoding,
33-
compression_override,
34-
max_message_size,
35-
);
36-
37-
EncodeBody::new_server(stream)
38-
}
39-
40-
/// Turns a stream of grpc messages into [EncodeBody] which is used by grpc clients for
41-
/// turning the messages into http frames for sending over the network.
42-
pub fn encode_client<T, U>(
43-
encoder: T,
44-
source: U,
45-
compression_encoding: Option<CompressionEncoding>,
46-
max_message_size: Option<usize>,
47-
) -> EncodeBody<impl Stream<Item = Result<Bytes, Status>>>
48-
where
49-
T: Encoder<Error = Status>,
50-
U: Stream<Item = T::Item>,
51-
{
52-
let stream = EncodedBytes::new(
53-
encoder,
54-
source.fuse().map(Ok),
55-
compression_encoding,
56-
SingleMessageCompressionOverride::default(),
57-
max_message_size,
58-
);
59-
EncodeBody::new_client(stream)
60-
}
14+
use tokio_stream::{adapters::Fuse, Stream, StreamExt};
6115

6216
/// Combinator for efficient encoding of messages into reasonably sized buffers.
6317
/// EncodedBytes encodes ready messages from its delegate stream into a BytesMut,
@@ -66,13 +20,9 @@ where
6620
/// * The encoded buffer surpasses YIELD_THRESHOLD.
6721
#[pin_project(project = EncodedBytesProj)]
6822
#[derive(Debug)]
69-
pub(crate) struct EncodedBytes<T, U>
70-
where
71-
T: Encoder<Error = Status>,
72-
U: Stream<Item = Result<T::Item, Status>>,
73-
{
23+
struct EncodedBytes<T, U> {
7424
#[pin]
75-
source: U,
25+
source: Fuse<U>,
7626
encoder: T,
7727
compression_encoding: Option<CompressionEncoding>,
7828
max_message_size: Option<usize>,
@@ -81,12 +31,7 @@ where
8131
error: Option<Status>,
8232
}
8333

84-
impl<T, U> EncodedBytes<T, U>
85-
where
86-
T: Encoder<Error = Status>,
87-
U: Stream<Item = Result<T::Item, Status>>,
88-
{
89-
// `source` should be fused stream.
34+
impl<T: Encoder, U: Stream> EncodedBytes<T, U> {
9035
fn new(
9136
encoder: T,
9237
source: U,
@@ -111,7 +56,7 @@ where
11156
};
11257

11358
Self {
114-
source,
59+
source: source.fuse(),
11560
encoder,
11661
compression_encoding,
11762
max_message_size,
@@ -270,9 +215,9 @@ enum Role {
270215
/// A specialized implementation of [Body] for encoding [Result<Bytes, Status>].
271216
#[pin_project]
272217
#[derive(Debug)]
273-
pub struct EncodeBody<S> {
218+
pub struct EncodeBody<T, U> {
274219
#[pin]
275-
inner: S,
220+
inner: EncodedBytes<T, U>,
276221
state: EncodeState,
277222
}
278223

@@ -283,10 +228,23 @@ struct EncodeState {
283228
is_end_stream: bool,
284229
}
285230

286-
impl<S> EncodeBody<S> {
287-
fn new_client(inner: S) -> Self {
231+
impl<T: Encoder, U: Stream> EncodeBody<T, U> {
232+
/// Turns a stream of grpc messages into [EncodeBody] which is used by grpc clients for
233+
/// turning the messages into http frames for sending over the network.
234+
pub fn new_client(
235+
encoder: T,
236+
source: U,
237+
compression_encoding: Option<CompressionEncoding>,
238+
max_message_size: Option<usize>,
239+
) -> Self {
288240
Self {
289-
inner,
241+
inner: EncodedBytes::new(
242+
encoder,
243+
source,
244+
compression_encoding,
245+
SingleMessageCompressionOverride::default(),
246+
max_message_size,
247+
),
290248
state: EncodeState {
291249
error: None,
292250
role: Role::Client,
@@ -295,9 +253,23 @@ impl<S> EncodeBody<S> {
295253
}
296254
}
297255

298-
fn new_server(inner: S) -> Self {
256+
/// Turns a stream of grpc results (message or error status) into [EncodeBody] which is used by grpc
257+
/// servers for turning the messages into http frames for sending over the network.
258+
pub fn new_server(
259+
encoder: T,
260+
source: U,
261+
compression_encoding: Option<CompressionEncoding>,
262+
compression_override: SingleMessageCompressionOverride,
263+
max_message_size: Option<usize>,
264+
) -> Self {
299265
Self {
300-
inner,
266+
inner: EncodedBytes::new(
267+
encoder,
268+
source,
269+
compression_encoding,
270+
compression_override,
271+
max_message_size,
272+
),
301273
state: EncodeState {
302274
error: None,
303275
role: Role::Server,
@@ -328,9 +300,10 @@ impl EncodeState {
328300
}
329301
}
330302

331-
impl<S> Body for EncodeBody<S>
303+
impl<T, U> Body for EncodeBody<T, U>
332304
where
333-
S: Stream<Item = Result<Bytes, Status>>,
305+
T: Encoder<Error = Status>,
306+
U: Stream<Item = Result<T::Item, Status>>,
334307
{
335308
type Data = Bytes;
336309
type Error = Status;

tonic/src/codec/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::io;
1616
pub use self::buffer::{DecodeBuf, EncodeBuf};
1717
pub use self::compression::{CompressionEncoding, EnabledCompressionEncodings};
1818
pub use self::decode::Streaming;
19-
pub use self::encode::{encode_client, encode_server, EncodeBody};
19+
pub use self::encode::EncodeBody;
2020
#[cfg(feature = "prost")]
2121
pub use self::prost::ProstCodec;
2222

tonic/src/codec/prost.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ fn from_decode_error(error: prost::DecodeError) -> crate::Status {
151151
mod tests {
152152
use crate::codec::compression::SingleMessageCompressionOverride;
153153
use crate::codec::{
154-
encode_server, DecodeBuf, Decoder, EncodeBuf, Encoder, Streaming, HEADER_SIZE,
154+
DecodeBuf, Decoder, EncodeBody, EncodeBuf, Encoder, Streaming, HEADER_SIZE,
155155
};
156156
use crate::Status;
157157
use bytes::{Buf, BufMut, BytesMut};
@@ -228,7 +228,7 @@ mod tests {
228228
let messages = std::iter::repeat_with(move || Ok::<_, Status>(msg.clone())).take(10000);
229229
let source = tokio_stream::iter(messages);
230230

231-
let mut body = pin!(encode_server(
231+
let mut body = pin!(EncodeBody::new_server(
232232
encoder,
233233
source,
234234
None,
@@ -250,7 +250,7 @@ mod tests {
250250
let messages = std::iter::once(Ok::<_, Status>(msg));
251251
let source = tokio_stream::iter(messages);
252252

253-
let mut body = pin!(encode_server(
253+
let mut body = pin!(EncodeBody::new_server(
254254
encoder,
255255
source,
256256
None,
@@ -278,14 +278,16 @@ mod tests {
278278
#[cfg(not(target_family = "windows"))]
279279
#[tokio::test]
280280
async fn encode_too_big() {
281+
use crate::codec::EncodeBody;
282+
281283
let encoder = MockEncoder::default();
282284

283285
let msg = vec![0u8; u32::MAX as usize + 1];
284286

285287
let messages = std::iter::once(Ok::<_, Status>(msg));
286288
let source = tokio_stream::iter(messages);
287289

288-
let mut body = pin!(encode_server(
290+
let mut body = pin!(EncodeBody::new_server(
289291
encoder,
290292
source,
291293
None,

tonic/src/server/grpc.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use crate::codec::compression::{
22
CompressionEncoding, EnabledCompressionEncodings, SingleMessageCompressionOverride,
33
};
4+
use crate::codec::EncodeBody;
45
use crate::metadata::GRPC_CONTENT_TYPE;
56
use crate::{
67
body::BoxBody,
7-
codec::{encode_server, Codec, Streaming},
8+
codec::{Codec, Streaming},
89
server::{ClientStreamingService, ServerStreamingService, StreamingService, UnaryService},
910
Request, Status,
1011
};
@@ -447,7 +448,7 @@ where
447448
);
448449
}
449450

450-
let body = encode_server(
451+
let body = EncodeBody::new_server(
451452
self.codec.encoder(),
452453
body,
453454
accept_encoding,

0 commit comments

Comments
 (0)