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}