tonic/codec/
mod.rs

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