laminar_db/pipeline/
mod.rs1pub mod callback;
8pub mod config;
9pub mod streaming_coordinator;
10
11pub(crate) use callback::CheckpointCompletion;
12pub use callback::{
13 BarrierOutcome, CheckpointAssignmentAdmission, CheckpointControlOutcome, CycleError,
14 CycleOutcome, PipelineCallback, SkipReason, SourceRegistration,
15};
16pub use config::{CheckpointSchedule, PipelineConfig};
17pub use streaming_coordinator::{ExitReason, StreamingCoordinator, StreamingCoordinatorRuntime};
18
19use laminar_sql::parser::EmitClause;
20use laminar_sql::translator::{JoinOperatorConfig, OrderOperatorConfig, WindowOperatorConfig};
21
22const CONTROL_MUTATION_PENDING: u8 = 0;
23const CONTROL_MUTATION_APPLIED: u8 = 1;
24const CONTROL_MUTATION_CANCELLED: u8 = 2;
25
26#[derive(Clone, Copy, Debug, Eq, PartialEq)]
27pub(crate) enum ControlMutationState {
28 Pending,
29 Applied,
30 Cancelled,
31}
32
33#[derive(Debug)]
34pub(crate) struct ControlMutation {
35 state: std::sync::atomic::AtomicU8,
36}
37
38impl ControlMutation {
39 pub(crate) fn new() -> Self {
40 Self {
41 state: std::sync::atomic::AtomicU8::new(CONTROL_MUTATION_PENDING),
42 }
43 }
44
45 pub(crate) fn try_apply(&self) -> bool {
46 self.state
47 .compare_exchange(
48 CONTROL_MUTATION_PENDING,
49 CONTROL_MUTATION_APPLIED,
50 std::sync::atomic::Ordering::AcqRel,
51 std::sync::atomic::Ordering::Acquire,
52 )
53 .is_ok()
54 }
55
56 pub(crate) fn cancel(&self) -> ControlMutationState {
57 match self.state.compare_exchange(
58 CONTROL_MUTATION_PENDING,
59 CONTROL_MUTATION_CANCELLED,
60 std::sync::atomic::Ordering::AcqRel,
61 std::sync::atomic::Ordering::Acquire,
62 ) {
63 Ok(_) | Err(CONTROL_MUTATION_CANCELLED) => ControlMutationState::Cancelled,
64 Err(CONTROL_MUTATION_APPLIED) => ControlMutationState::Applied,
65 Err(_) => unreachable!("control mutation contains an invalid state"),
66 }
67 }
68
69 pub(crate) fn state(&self) -> ControlMutationState {
70 match self.state.load(std::sync::atomic::Ordering::Acquire) {
71 CONTROL_MUTATION_PENDING => ControlMutationState::Pending,
72 CONTROL_MUTATION_APPLIED => ControlMutationState::Applied,
73 CONTROL_MUTATION_CANCELLED => ControlMutationState::Cancelled,
74 _ => unreachable!("control mutation contains an invalid state"),
75 }
76 }
77}
78
79#[derive(Debug)]
81pub struct ControlMsg(ControlMsgKind);
82
83#[derive(Debug)]
84#[allow(clippy::large_enum_variant)]
85pub(crate) enum ControlMsgKind {
86 AddStream {
87 name: String,
88 sql: String,
89 emit_clause: Option<EmitClause>,
90 window_config: Option<WindowOperatorConfig>,
91 order_config: Option<OrderOperatorConfig>,
92 join_config: Option<Vec<JoinOperatorConfig>>,
93 incremental: bool,
94 reply: tokio::sync::oneshot::Sender<Result<(), crate::error::DbError>>,
95 mutation: std::sync::Arc<ControlMutation>,
96 },
97 DropStreams {
98 names: Vec<String>,
99 reply: tokio::sync::oneshot::Sender<Result<(), crate::error::DbError>>,
100 mutation: std::sync::Arc<ControlMutation>,
101 },
102}
103
104impl ControlMsg {
105 pub(crate) fn add_stream(
106 name: String,
107 sql: String,
108 emit_clause: Option<EmitClause>,
109 window_config: Option<WindowOperatorConfig>,
110 order_config: Option<OrderOperatorConfig>,
111 join_config: Option<Vec<JoinOperatorConfig>>,
112 incremental: bool,
113 reply: tokio::sync::oneshot::Sender<Result<(), crate::error::DbError>>,
114 mutation: std::sync::Arc<ControlMutation>,
115 ) -> Self {
116 Self(ControlMsgKind::AddStream {
117 name,
118 sql,
119 emit_clause,
120 window_config,
121 order_config,
122 join_config,
123 incremental,
124 reply,
125 mutation,
126 })
127 }
128
129 pub(crate) fn drop_streams(
130 names: Vec<String>,
131 reply: tokio::sync::oneshot::Sender<Result<(), crate::error::DbError>>,
132 mutation: std::sync::Arc<ControlMutation>,
133 ) -> Self {
134 Self(ControlMsgKind::DropStreams {
135 names,
136 reply,
137 mutation,
138 })
139 }
140
141 pub(crate) fn into_kind(self) -> ControlMsgKind {
142 self.0
143 }
144}