streamkit_core/node_config.rs
1// SPDX-FileCopyrightText: © 2025 StreamKit Contributors
2//
3// SPDX-License-Identifier: MPL-2.0
4
5//! Runtime configuration for internal node buffers.
6//!
7//! This module provides a global configuration mechanism for internal buffer settings
8//! used by codec and container nodes. These settings are typically set once at server
9//! startup and remain constant for the lifetime of the process.
10//!
11//! ## Usage
12//!
13//! Server startup:
14//! ```ignore
15//! use streamkit_core::node_config::{set_node_buffer_config, NodeBufferConfig};
16//!
17//! let config = NodeBufferConfig {
18//! codec_channel_capacity: 32,
19//! stream_channel_capacity: 8,
20//! demuxer_buffer_size: 65536,
21//! moq_peer_channel_capacity: 100,
22//! };
23//! set_node_buffer_config(config);
24//! ```
25//!
26//! Node implementation:
27//! ```ignore
28//! use streamkit_core::node_config::get_codec_channel_capacity;
29//!
30//! let (tx, rx) = mpsc::channel(get_codec_channel_capacity());
31//! ```
32//!
33//! ## Default Values
34//!
35//! If `set_node_buffer_config` is never called, the getter functions return sensible
36//! defaults based on production experience:
37//!
38//! - `codec_channel_capacity`: 32 packets
39//! - `stream_channel_capacity`: 8 packets
40//! - `demuxer_buffer_size`: 65536 bytes (64KB)
41//! - `moq_peer_channel_capacity`: 100 packets (MoQ transport internal queues)
42
43use std::sync::OnceLock;
44
45/// Default capacity for codec async/blocking handoff channels.
46const DEFAULT_CODEC_CHANNEL_CAPACITY: usize = 32;
47
48/// Default capacity for streaming reader channels (container demuxers).
49const DEFAULT_STREAM_CHANNEL_CAPACITY: usize = 8;
50
51/// Default duplex buffer size for ogg demuxer (64KB).
52const DEFAULT_DEMUXER_BUFFER_SIZE: usize = 64 * 1024;
53
54/// Default capacity for MoQ transport peer internal channels.
55const DEFAULT_MOQ_PEER_CHANNEL_CAPACITY: usize = 100;
56
57/// Runtime configuration for node internal buffers.
58///
59/// These settings affect the async/blocking handoff channels in codec and container nodes.
60/// Most users should not need to modify these values.
61#[derive(Debug, Clone)]
62pub struct NodeBufferConfig {
63 /// Capacity for codec processing channels (e.g. Opus encoder/decoder).
64 /// Used for async/blocking handoff in codec nodes.
65 pub codec_channel_capacity: usize,
66
67 /// Capacity for streaming reader channels (container demuxers).
68 /// Smaller than codec channels because container frames may be larger.
69 pub stream_channel_capacity: usize,
70
71 /// Duplex buffer size for ogg demuxer in bytes.
72 pub demuxer_buffer_size: usize,
73
74 /// Capacity for MoQ transport peer internal channels (packets).
75 ///
76 /// Used by MoQ transport nodes for per-connection send/receive coordination.
77 /// This is not the same as engine graph channel capacities; it only affects the
78 /// internal queueing within the transport node.
79 pub moq_peer_channel_capacity: usize,
80}
81
82impl Default for NodeBufferConfig {
83 fn default() -> Self {
84 Self {
85 codec_channel_capacity: DEFAULT_CODEC_CHANNEL_CAPACITY,
86 stream_channel_capacity: DEFAULT_STREAM_CHANNEL_CAPACITY,
87 demuxer_buffer_size: DEFAULT_DEMUXER_BUFFER_SIZE,
88 moq_peer_channel_capacity: DEFAULT_MOQ_PEER_CHANNEL_CAPACITY,
89 }
90 }
91}
92
93/// Global storage for the node buffer configuration.
94static NODE_BUFFER_CONFIG: OnceLock<NodeBufferConfig> = OnceLock::new();
95
96/// Sets the global node buffer configuration.
97///
98/// This should be called once at server startup, before any nodes are created.
99/// Subsequent calls are ignored (the first configuration wins).
100///
101/// # Example
102///
103/// ```ignore
104/// use streamkit_core::node_config::{set_node_buffer_config, NodeBufferConfig};
105///
106/// set_node_buffer_config(NodeBufferConfig {
107/// codec_channel_capacity: 64, // Increased for high-throughput scenarios
108/// stream_channel_capacity: 16,
109/// demuxer_buffer_size: 128 * 1024, // 128KB buffer
110/// moq_peer_channel_capacity: 200,
111/// });
112/// ```
113pub fn set_node_buffer_config(config: NodeBufferConfig) {
114 if NODE_BUFFER_CONFIG.set(config).is_err() {
115 tracing::warn!("Node buffer config already set, ignoring new configuration");
116 }
117}
118
119/// Returns the configured codec channel capacity.
120///
121/// Used by codec nodes that offload CPU work to blocking tasks (e.g. Opus).
122/// Returns the default (32) if no configuration was set.
123#[inline]
124pub fn get_codec_channel_capacity() -> usize {
125 NODE_BUFFER_CONFIG.get().map_or(DEFAULT_CODEC_CHANNEL_CAPACITY, |c| c.codec_channel_capacity)
126}
127
128/// Returns the configured stream channel capacity.
129///
130/// Used by streaming readers that hand off `Bytes` into blocking demux/decode tasks
131/// (container demuxers and some non-Opus codecs).
132/// Returns the default (8) if no configuration was set.
133#[inline]
134pub fn get_stream_channel_capacity() -> usize {
135 NODE_BUFFER_CONFIG.get().map_or(DEFAULT_STREAM_CHANNEL_CAPACITY, |c| c.stream_channel_capacity)
136}
137
138/// Returns the configured demuxer buffer size in bytes.
139///
140/// Used by ogg demuxer for its duplex buffer. Returns the default (64KB)
141/// if no configuration was set.
142#[inline]
143pub fn get_demuxer_buffer_size() -> usize {
144 NODE_BUFFER_CONFIG.get().map_or(DEFAULT_DEMUXER_BUFFER_SIZE, |c| c.demuxer_buffer_size)
145}
146
147/// Returns the configured MoQ peer channel capacity.
148///
149/// Used by MoQ transport peer tasks for per-connection internal buffering.
150/// Returns the default (100) if no configuration was set.
151#[inline]
152pub fn get_moq_peer_channel_capacity() -> usize {
153 NODE_BUFFER_CONFIG
154 .get()
155 .map_or(DEFAULT_MOQ_PEER_CHANNEL_CAPACITY, |c| c.moq_peer_channel_capacity)
156}
157
158#[cfg(test)]
159mod tests {
160 use super::*;
161
162 #[test]
163 fn test_default_values() {
164 // Without setting config, should return defaults
165 // Note: This test may fail if run after other tests that set the config
166 assert_eq!(DEFAULT_CODEC_CHANNEL_CAPACITY, 32);
167 assert_eq!(DEFAULT_STREAM_CHANNEL_CAPACITY, 8);
168 assert_eq!(DEFAULT_DEMUXER_BUFFER_SIZE, 64 * 1024);
169 assert_eq!(DEFAULT_MOQ_PEER_CHANNEL_CAPACITY, 100);
170 }
171}