Skip to main content

termwright_protocol/
limits.rs

1//! Protocol limits. Callers may tighten the defaults, never widen the maxima.
2
3use serde::{Deserialize, Serialize};
4
5/// Per-session capacity ceilings, named as they appear on the wire.
6/// `limits` is the one object on the wire that grows between protocol
7/// versions, so unknown fields are ignored rather than rejected: a client that
8/// refused a ceiling it had never heard of would drop the channel every time
9/// the protocol gained one.
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
11#[serde(rename_all = "camelCase")]
12pub struct Limits {
13    /// Per-frame byte ceiling, header excluded.
14    pub max_frame_bytes: usize,
15    /// Serialised size ceiling for one snapshot.
16    pub max_snapshot_bytes: usize,
17    /// Node and root-id count ceiling per snapshot.
18    pub max_nodes: usize,
19    /// Structural nesting ceiling, roots at depth 1.
20    pub max_depth: usize,
21    /// UTF-8 byte ceiling for any single string.
22    pub max_string_bytes: usize,
23    /// Ceiling on `labelledBy`/`describedBy`/`textRanges` entries.
24    pub max_relation_targets: usize,
25    /// Frames the driver buffers before applying back-pressure.
26    pub max_queued_frames: usize,
27    /// Concurrent waiters the driver will track.
28    pub max_pending_waiters: usize,
29    /// Concurrent sessions the driver will hold open.
30    pub max_sessions: usize,
31    /// Byte ceiling for one serialised application log record.
32    pub max_log_record_bytes: usize,
33    /// Log records the driver buffers per session before evicting the oldest.
34    pub max_log_queue: usize,
35}
36
37/// What an adapter assumes until `hello-ack` says otherwise.
38pub const DEFAULT_LIMITS: Limits = Limits {
39    max_frame_bytes: 1024 * 1024,
40    max_snapshot_bytes: 2 * 1024 * 1024,
41    max_nodes: 5_000,
42    max_depth: 64,
43    max_string_bytes: 16 * 1024,
44    max_relation_targets: 64,
45    max_queued_frames: 32,
46    max_pending_waiters: 256,
47    max_sessions: 16,
48    max_log_record_bytes: 32 * 1024,
49    max_log_queue: 1_000,
50};
51
52/// The widest configuration either side may accept.
53pub const ABSOLUTE_LIMITS: Limits = Limits {
54    max_frame_bytes: 8 * 1024 * 1024,
55    max_snapshot_bytes: 8 * 1024 * 1024,
56    max_nodes: 50_000,
57    max_depth: 256,
58    max_string_bytes: 256 * 1024,
59    max_relation_targets: 1_024,
60    max_queued_frames: 256,
61    max_pending_waiters: 4_096,
62    max_sessions: 128,
63    max_log_record_bytes: 256 * 1024,
64    max_log_queue: 10_000,
65};
66
67/// Milliseconds a driver waits for a `hello` before settling the session as
68/// generic (non-semantic).
69pub const DEFAULT_NEGOTIATION_MS: u64 = 2_000;
70
71impl Default for Limits {
72    fn default() -> Self {
73        DEFAULT_LIMITS
74    }
75}