xref: /tonic/tonic/src/codec/mod.rs (revision 3c900ebd)
1 //! Generic encoding and decoding.
2 //!
3 //! This module contains the generic `Codec`, `Encoder` and `Decoder` traits
4 //! and a protobuf codec based on prost.
5 
6 mod buffer;
7 pub(crate) mod compression;
8 mod decode;
9 mod encode;
10 #[cfg(feature = "prost")]
11 mod prost;
12 
13 use crate::Status;
14 use std::io;
15 
16 pub use self::buffer::{DecodeBuf, EncodeBuf};
17 pub use self::compression::{CompressionEncoding, EnabledCompressionEncodings};
18 pub use self::decode::Streaming;
19 pub use self::encode::EncodeBody;
20 #[cfg(feature = "prost")]
21 pub use self::prost::ProstCodec;
22 
23 /// Unless overridden, this is the buffer size used for encoding requests.
24 /// This is spent per-rpc, so you may wish to adjust it. The default is
25 /// pretty good for most uses, but if you have a ton of concurrent rpcs
26 /// you may find it too expensive.
27 const DEFAULT_CODEC_BUFFER_SIZE: usize = 8 * 1024;
28 const DEFAULT_YIELD_THRESHOLD: usize = 32 * 1024;
29 
30 /// Settings for how tonic allocates and grows buffers.
31 ///
32 /// Tonic eagerly allocates the buffer_size per RPC, and grows
33 /// the buffer by buffer_size increments to handle larger messages.
34 /// Buffer size defaults to 8KiB.
35 ///
36 /// Example:
37 /// ```ignore
38 /// Buffer start:       | 8kb |
39 /// Message received:   |   24612 bytes    |
40 /// Buffer grows:       | 8kb | 8kb | 8kb | 8kb |
41 /// ```
42 ///
43 /// The buffer grows to the next largest buffer_size increment of
44 /// 32768 to hold 24612 bytes, which is just slightly too large for
45 /// the previous buffer increment of 24576.
46 ///
47 /// If you use a smaller buffer size you will waste less memory, but
48 /// you will allocate more frequently. If one way or the other matters
49 /// more to you, you may wish to customize your tonic Codec (see
50 /// codec_buffers example).
51 ///
52 /// Yield threshold is an optimization for streaming rpcs. Sometimes
53 /// you may have many small messages ready to send. When they are ready,
54 /// it is a much more efficient use of system resources to batch them
55 /// together into one larger send(). The yield threshold controls how
56 /// much you want to bulk up such a batch of ready-to-send messages.
57 /// The larger your yield threshold the more you will batch - and
58 /// consequently allocate contiguous memory, which might be relevant
59 /// if you're considering large numbers here.
60 /// If your server streaming rpc does not reach the yield threshold
61 /// before it reaches Poll::Pending (meaning, it's waiting for more
62 /// data from wherever you're streaming from) then Tonic will just send
63 /// along a smaller batch. Yield threshold is an upper-bound, it will
64 /// not affect the responsiveness of your streaming rpc (for reasonable
65 /// sizes of yield threshold).
66 /// Yield threshold defaults to 32 KiB.
67 #[derive(Clone, Copy, Debug)]
68 pub struct BufferSettings {
69     buffer_size: usize,
70     yield_threshold: usize,
71 }
72 
73 impl BufferSettings {
74     /// Create a new `BufferSettings`
new(buffer_size: usize, yield_threshold: usize) -> Self75     pub fn new(buffer_size: usize, yield_threshold: usize) -> Self {
76         Self {
77             buffer_size,
78             yield_threshold,
79         }
80     }
81 }
82 
83 impl Default for BufferSettings {
default() -> Self84     fn default() -> Self {
85         Self {
86             buffer_size: DEFAULT_CODEC_BUFFER_SIZE,
87             yield_threshold: DEFAULT_YIELD_THRESHOLD,
88         }
89     }
90 }
91 
92 // 5 bytes
93 const HEADER_SIZE: usize =
94     // compression flag
95     std::mem::size_of::<u8>() +
96     // data length
97     std::mem::size_of::<u32>();
98 
99 // The default maximum uncompressed size in bytes for a message. Defaults to 4MB.
100 const DEFAULT_MAX_RECV_MESSAGE_SIZE: usize = 4 * 1024 * 1024;
101 const DEFAULT_MAX_SEND_MESSAGE_SIZE: usize = usize::MAX;
102 
103 /// Trait that knows how to encode and decode gRPC messages.
104 pub trait Codec {
105     /// The encodable message.
106     type Encode: Send + 'static;
107     /// The decodable message.
108     type Decode: Send + 'static;
109 
110     /// The encoder that can encode a message.
111     type Encoder: Encoder<Item = Self::Encode, Error = Status> + Send + 'static;
112     /// The encoder that can decode a message.
113     type Decoder: Decoder<Item = Self::Decode, Error = Status> + Send + 'static;
114 
115     /// Fetch the encoder.
encoder(&mut self) -> Self::Encoder116     fn encoder(&mut self) -> Self::Encoder;
117     /// Fetch the decoder.
decoder(&mut self) -> Self::Decoder118     fn decoder(&mut self) -> Self::Decoder;
119 }
120 
121 /// Encodes gRPC message types
122 pub trait Encoder {
123     /// The type that is encoded.
124     type Item;
125 
126     /// The type of encoding errors.
127     ///
128     /// The type of unrecoverable frame encoding errors.
129     type Error: From<io::Error>;
130 
131     /// Encodes a message into the provided buffer.
encode(&mut self, item: Self::Item, dst: &mut EncodeBuf<'_>) -> Result<(), Self::Error>132     fn encode(&mut self, item: Self::Item, dst: &mut EncodeBuf<'_>) -> Result<(), Self::Error>;
133 
134     /// Controls how tonic creates and expands encode buffers.
buffer_settings(&self) -> BufferSettings135     fn buffer_settings(&self) -> BufferSettings {
136         BufferSettings::default()
137     }
138 }
139 
140 /// Decodes gRPC message types
141 pub trait Decoder {
142     /// The type that is decoded.
143     type Item;
144 
145     /// The type of unrecoverable frame decoding errors.
146     type Error: From<io::Error>;
147 
148     /// Decode a message from the buffer.
149     ///
150     /// The buffer will contain exactly the bytes of a full message. There
151     /// is no need to get the length from the bytes, gRPC framing is handled
152     /// for you.
decode(&mut self, src: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error>153     fn decode(&mut self, src: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error>;
154 
155     /// Controls how tonic creates and expands decode buffers.
buffer_settings(&self) -> BufferSettings156     fn buffer_settings(&self) -> BufferSettings {
157         BufferSettings::default()
158     }
159 }
160