tonic/codec/mod.rs
1/*
2 *
3 * Copyright 2025 gRPC authors.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
25//! Generic encoding and decoding.
26//!
27//! This module contains the generic `Codec`, `Encoder` and `Decoder` traits.
28
29mod buffer;
30pub(crate) mod compression;
31mod decode;
32mod encode;
33use crate::Status;
34use std::io;
35
36pub use self::buffer::{DecodeBuf, EncodeBuf};
37pub use self::compression::{CompressionEncoding, EnabledCompressionEncodings};
38pub use self::decode::Streaming;
39pub use self::encode::EncodeBody;
40
41// Doc hidden since this is used in a test in another crate, we can expose this publically later
42// if we need it.
43#[doc(hidden)]
44pub use self::compression::SingleMessageCompressionOverride;
45
46/// Unless overridden, this is the buffer size used for encoding requests.
47/// This is spent per-rpc, so you may wish to adjust it. The default is
48/// pretty good for most uses, but if you have a ton of concurrent rpcs
49/// you may find it too expensive.
50const DEFAULT_CODEC_BUFFER_SIZE: usize = 8 * 1024;
51const DEFAULT_YIELD_THRESHOLD: usize = 32 * 1024;
52
53/// Settings for how tonic allocates and grows buffers.
54///
55/// Tonic eagerly allocates the buffer_size per RPC, and grows
56/// the buffer by buffer_size increments to handle larger messages.
57/// Buffer size defaults to 8KiB.
58///
59/// Example:
60/// ```ignore
61/// Buffer start: | 8kb |
62/// Message received: | 24612 bytes |
63/// Buffer grows: | 8kb | 8kb | 8kb | 8kb |
64/// ```
65///
66/// The buffer grows to the next largest buffer_size increment of
67/// 32768 to hold 24612 bytes, which is just slightly too large for
68/// the previous buffer increment of 24576.
69///
70/// If you use a smaller buffer size you will waste less memory, but
71/// you will allocate more frequently. If one way or the other matters
72/// more to you, you may wish to customize your tonic Codec (see
73/// codec_buffers example).
74///
75/// Yield threshold is an optimization for streaming rpcs. Sometimes
76/// you may have many small messages ready to send. When they are ready,
77/// it is a much more efficient use of system resources to batch them
78/// together into one larger send(). The yield threshold controls how
79/// much you want to bulk up such a batch of ready-to-send messages.
80/// The larger your yield threshold the more you will batch - and
81/// consequently allocate contiguous memory, which might be relevant
82/// if you're considering large numbers here.
83/// If your server streaming rpc does not reach the yield threshold
84/// before it reaches Poll::Pending (meaning, it's waiting for more
85/// data from wherever you're streaming from) then Tonic will just send
86/// along a smaller batch. Yield threshold is an upper-bound, it will
87/// not affect the responsiveness of your streaming rpc (for reasonable
88/// sizes of yield threshold).
89/// Yield threshold defaults to 32 KiB.
90#[derive(Clone, Copy, Debug)]
91pub struct BufferSettings {
92 buffer_size: usize,
93 yield_threshold: usize,
94}
95
96impl BufferSettings {
97 /// Create a new `BufferSettings`
98 pub fn new(buffer_size: usize, yield_threshold: usize) -> Self {
99 Self {
100 buffer_size,
101 yield_threshold,
102 }
103 }
104}
105
106impl Default for BufferSettings {
107 fn default() -> Self {
108 Self {
109 buffer_size: DEFAULT_CODEC_BUFFER_SIZE,
110 yield_threshold: DEFAULT_YIELD_THRESHOLD,
111 }
112 }
113}
114
115// Doc hidden because it's used in tests in another crate but not part of the
116// public api.
117#[doc(hidden)]
118pub const HEADER_SIZE: usize =
119 // compression flag
120 std::mem::size_of::<u8>() +
121 // data length
122 std::mem::size_of::<u32>();
123
124// The default maximum uncompressed size in bytes for a message. Defaults to 4MB.
125const DEFAULT_MAX_RECV_MESSAGE_SIZE: usize = 4 * 1024 * 1024;
126const DEFAULT_MAX_SEND_MESSAGE_SIZE: usize = usize::MAX;
127
128/// Trait that knows how to encode and decode gRPC messages.
129pub trait Codec {
130 /// The encodable message.
131 type Encode: Send + 'static;
132 /// The decodable message.
133 type Decode: Send + 'static;
134
135 /// The encoder that can encode a message.
136 type Encoder: Encoder<Item = Self::Encode, Error = Status> + Send + 'static;
137 /// The decoder that can decode a message.
138 type Decoder: Decoder<Item = Self::Decode, Error = Status> + Send + 'static;
139
140 /// Fetch the encoder.
141 fn encoder(&mut self) -> Self::Encoder;
142 /// Fetch the decoder.
143 fn decoder(&mut self) -> Self::Decoder;
144}
145
146/// Encodes gRPC message types
147pub trait Encoder {
148 /// The type that is encoded.
149 type Item;
150
151 /// The type of encoding errors.
152 ///
153 /// The type of unrecoverable frame encoding errors.
154 type Error: From<io::Error>;
155
156 /// Encodes a message into the provided buffer.
157 fn encode(&mut self, item: Self::Item, dst: &mut EncodeBuf<'_>) -> Result<(), Self::Error>;
158
159 /// Controls how tonic creates and expands encode buffers.
160 fn buffer_settings(&self) -> BufferSettings {
161 BufferSettings::default()
162 }
163}
164
165/// Decodes gRPC message types
166pub trait Decoder {
167 /// The type that is decoded.
168 type Item;
169
170 /// The type of unrecoverable frame decoding errors.
171 type Error: From<io::Error>;
172
173 /// Decode a message from the buffer.
174 ///
175 /// The buffer will contain exactly the bytes of a full message. There
176 /// is no need to get the length from the bytes, gRPC framing is handled
177 /// for you.
178 fn decode(&mut self, src: &mut DecodeBuf<'_>) -> Result<Option<Self::Item>, Self::Error>;
179
180 /// Controls how tonic creates and expands decode buffers.
181 fn buffer_settings(&self) -> BufferSettings {
182 BufferSettings::default()
183 }
184}