pub mod constants;
pub mod errors;
pub mod frame;
pub mod receiver;
pub mod registry;
pub mod session;
pub mod writer;
pub use constants::*;
pub use errors::OpenStreamError;
pub use frame::{open_stream_frame_from_notification, OpenStreamFrame};
pub use receiver::OpenStreamReceiver;
pub use registry::{
OpenStreamRegistry, OpenStreamRegistryPolicy, OpenStreamSessionInit, RegistryAbortHook,
RegistryCloseHook,
};
pub use session::{
FrameOutcome, KeepaliveAction, OpenStreamSession, OpenStreamSessionOptions, PublishFrame,
};
pub use writer::{OnAbortHook, OnCloseHook, OpenStreamWriter, OpenStreamWriterOptions};
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct OpenStreamConfig {
pub enabled: bool,
pub max_concurrent_streams: usize,
pub max_buffered_chunks_per_stream: usize,
pub max_buffered_bytes_per_stream: usize,
pub idle_timeout_ms: u64,
pub probe_timeout_ms: u64,
pub close_grace_period_ms: u64,
pub max_total_timeout_ms: Option<u64>,
}
impl Default for OpenStreamConfig {
fn default() -> Self {
Self {
enabled: false,
max_concurrent_streams: constants::DEFAULT_MAX_CONCURRENT_OPEN_STREAMS,
max_buffered_chunks_per_stream: constants::DEFAULT_MAX_BUFFERED_CHUNKS_PER_STREAM,
max_buffered_bytes_per_stream: constants::DEFAULT_MAX_BUFFERED_BYTES_PER_STREAM,
idle_timeout_ms: constants::DEFAULT_OPEN_STREAM_IDLE_TIMEOUT_MS,
probe_timeout_ms: constants::DEFAULT_OPEN_STREAM_PROBE_TIMEOUT_MS,
close_grace_period_ms: constants::DEFAULT_OPEN_STREAM_CLOSE_GRACE_PERIOD_MS,
max_total_timeout_ms: None,
}
}
}
impl OpenStreamConfig {
pub fn enabled() -> Self {
Self {
enabled: true,
..Self::default()
}
}
pub fn with_enabled(mut self, enabled: bool) -> Self {
self.enabled = enabled;
self
}
pub fn with_max_concurrent_streams(mut self, max: usize) -> Self {
self.max_concurrent_streams = max;
self
}
pub fn with_max_buffered_chunks_per_stream(mut self, max: usize) -> Self {
self.max_buffered_chunks_per_stream = max;
self
}
pub fn with_max_buffered_bytes_per_stream(mut self, max: usize) -> Self {
self.max_buffered_bytes_per_stream = max;
self
}
pub fn with_idle_timeout_ms(mut self, ms: u64) -> Self {
self.idle_timeout_ms = ms;
self
}
pub fn with_probe_timeout_ms(mut self, ms: u64) -> Self {
self.probe_timeout_ms = ms;
self
}
pub fn with_close_grace_period_ms(mut self, ms: u64) -> Self {
self.close_grace_period_ms = ms;
self
}
pub fn with_max_total_timeout_ms(mut self, ms: Option<u64>) -> Self {
self.max_total_timeout_ms = ms;
self
}
}
impl From<&OpenStreamConfig> for OpenStreamRegistryPolicy {
fn from(config: &OpenStreamConfig) -> Self {
OpenStreamRegistryPolicy {
max_concurrent_streams: config.max_concurrent_streams,
max_buffered_chunks_per_stream: config.max_buffered_chunks_per_stream,
max_buffered_bytes_per_stream: config.max_buffered_bytes_per_stream,
idle_timeout_ms: config.idle_timeout_ms,
probe_timeout_ms: config.probe_timeout_ms,
close_grace_period_ms: config.close_grace_period_ms,
}
}
}
#[cfg(test)]
mod config_tests {
use super::*;
#[test]
fn default_is_disabled_with_ts_parity_knobs() {
let config = OpenStreamConfig::default();
assert!(!config.enabled);
assert!(OpenStreamConfig::default().with_enabled(true).enabled);
assert!(OpenStreamConfig::enabled().enabled);
assert_eq!(config.max_concurrent_streams, 64);
assert_eq!(config.max_buffered_chunks_per_stream, 64);
assert_eq!(config.max_buffered_bytes_per_stream, 512 * 1024);
assert_eq!(config.idle_timeout_ms, 30_000);
assert_eq!(config.probe_timeout_ms, 20_000);
assert_eq!(config.close_grace_period_ms, 5_000);
assert_eq!(config.max_total_timeout_ms, None);
}
#[test]
fn builders_opt_in_and_override() {
let config = OpenStreamConfig::default()
.with_enabled(true)
.with_max_concurrent_streams(8)
.with_max_buffered_bytes_per_stream(1024)
.with_max_total_timeout_ms(Some(60_000));
assert!(config.enabled);
assert_eq!(config.max_concurrent_streams, 8);
assert_eq!(config.max_buffered_bytes_per_stream, 1024);
assert_eq!(config.max_total_timeout_ms, Some(60_000));
assert!(OpenStreamConfig::enabled().enabled);
}
#[test]
fn projects_into_registry_policy() {
let config = OpenStreamConfig::default()
.with_max_concurrent_streams(3)
.with_max_buffered_chunks_per_stream(5)
.with_max_buffered_bytes_per_stream(7)
.with_idle_timeout_ms(11)
.with_probe_timeout_ms(13)
.with_close_grace_period_ms(17);
let policy: OpenStreamRegistryPolicy = (&config).into();
assert_eq!(policy.max_concurrent_streams, 3);
assert_eq!(policy.max_buffered_chunks_per_stream, 5);
assert_eq!(policy.max_buffered_bytes_per_stream, 7);
assert_eq!(policy.idle_timeout_ms, 11);
assert_eq!(policy.probe_timeout_ms, 13);
assert_eq!(policy.close_grace_period_ms, 17);
}
}