Skip to main content

laminar_db/pipeline/
config.rs

1//! Pipeline configuration.
2
3use std::time::Duration;
4
5use laminar_connectors::connector::DeliveryGuarantee;
6
7use crate::config::BackpressurePolicy;
8
9/// Checkpoint triggering configured for the running pipeline.
10///
11/// The three states mirror [`LaminarConfig::checkpoint`](crate::config::LaminarConfig::checkpoint)
12/// without allowing an enabled flag and timer interval to contradict each other.
13#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
14pub enum CheckpointSchedule {
15    /// No durable checkpoint service is configured.
16    #[default]
17    Disabled,
18    /// Checkpoints run only when explicitly requested.
19    Manual,
20    /// Checkpoints wait at least this long after a terminal outcome before the next automatic
21    /// admission; they may also be requested explicitly.
22    Periodic(Duration),
23}
24
25impl CheckpointSchedule {
26    /// Whether the durable checkpoint service is configured.
27    #[must_use]
28    pub const fn is_enabled(self) -> bool {
29        !matches!(self, Self::Disabled)
30    }
31
32    /// The periodic cadence, if automatic checkpoints are configured.
33    #[must_use]
34    pub const fn periodic_interval(self) -> Option<Duration> {
35        match self {
36            Self::Periodic(interval) => Some(interval),
37            Self::Disabled | Self::Manual => None,
38        }
39    }
40}
41
42/// Configuration for the event-driven connector pipeline.
43#[derive(Debug, Clone)]
44pub struct PipelineConfig {
45    /// Maximum records per `poll_batch()` call.
46    pub max_poll_records: usize,
47
48    /// Channel capacity for per-source `mpsc` sender → coordinator.
49    pub channel_capacity: usize,
50
51    /// Fallback poll interval when a source returns no `data_ready_notify`.
52    pub fallback_poll_interval: Duration,
53
54    /// Whether checkpoints are disabled, manual-only, or periodic.
55    pub checkpoint_schedule: CheckpointSchedule,
56
57    /// Sleep after the first event in a cycle to let more data accumulate.
58    ///
59    /// Bounds SQL executions per second without sacrificing data. The bounded
60    /// channel provides natural backpressure during the window. `ZERO` = no batching.
61    pub batch_window: Duration,
62
63    /// Sole checkpoint-derived control-plane budget. Each connector startup stage and checkpoint
64    /// barrier creates one absolute deadline from this duration; individual connectors cannot
65    /// reset it.
66    pub checkpoint_timeout: Duration,
67
68    /// End-to-end delivery guarantee for the pipeline.
69    pub delivery_guarantee: DeliveryGuarantee,
70
71    /// Maximum wall-clock time for a single processing cycle (nanoseconds). Default: 10ms.
72    pub cycle_budget_ns: u64,
73
74    /// Maximum wall-clock time for the message drain phase (nanoseconds). Default: 1ms.
75    pub drain_budget_ns: u64,
76
77    /// Maximum wall-clock time for per-query execution within a cycle (nanoseconds). Default: 8ms.
78    pub query_budget_ns: u64,
79
80    /// Maximum wall-clock time for background work after SQL execution (nanoseconds). Default: 5ms.
81    pub background_budget_ns: u64,
82
83    /// Per-input-port batch cap. Default: 256.
84    pub max_input_buf_batches: usize,
85
86    /// Per-input-port byte cap. `None` = disabled.
87    pub max_input_buf_bytes: Option<usize>,
88
89    /// What to do when either cap is exceeded.
90    pub backpressure_policy: BackpressurePolicy,
91
92    /// Isolate queries that share a source into independent failure domains.
93    /// Off: they fault and recover together; on: a fault holds back only its own offset.
94    pub shared_source_isolation: bool,
95
96    /// Per-source cap on the in-memory replay buffer used by `shared_source_isolation`.
97    /// On overflow the engine falls back to whole-pipeline recovery. Ignored when the
98    /// flag is off.
99    pub max_replay_buffer_bytes: usize,
100}
101
102impl Default for PipelineConfig {
103    fn default() -> Self {
104        Self {
105            max_poll_records: 1024,
106            channel_capacity: 64,
107            fallback_poll_interval: Duration::from_millis(10),
108            checkpoint_schedule: CheckpointSchedule::Disabled,
109            batch_window: Duration::from_millis(5),
110            checkpoint_timeout: Duration::from_secs(30),
111            delivery_guarantee: DeliveryGuarantee::default(),
112            cycle_budget_ns: 10_000_000,     // 10ms
113            drain_budget_ns: 1_000_000,      // 1ms
114            query_budget_ns: 8_000_000,      // 8ms
115            background_budget_ns: 5_000_000, // 5ms
116            max_input_buf_batches: 256,
117            max_input_buf_bytes: None,
118            backpressure_policy: BackpressurePolicy::default(),
119            shared_source_isolation: false,
120            max_replay_buffer_bytes: 256 * 1024 * 1024, // 256 MiB per source
121        }
122    }
123}
124
125impl PipelineConfig {
126    /// Private rollback budget for a failed connector startup stage. This is deliberately fixed:
127    /// cleanup is fail-safe implementation policy, not another latency tuning dimension.
128    pub(crate) const CONNECTOR_STARTUP_CLEANUP_TIMEOUT: Duration = Duration::from_secs(15);
129}