tonic_veecore/codec/
mod.rs

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