reifydb_engine/
watermark.rs1use reifydb_cdc::consume::watermark::compute_pinning_watermark;
5use reifydb_core::{
6 common::CommitVersion,
7 lifecycle::watermark::{EvictionWatermark, QueryWatermark},
8};
9use reifydb_transaction::transaction::Transaction;
10use reifydb_value::value::identity::IdentityId;
11use tracing::error;
12
13use crate::engine::StandardEngine;
14
15impl QueryWatermark for StandardEngine {
16 fn effective_gc_cutoff(&self) -> CommitVersion {
17 let qdu = self.query_done_until();
18 let lease_min = self.multi().leases().min_active().unwrap_or(CommitVersion(u64::MAX));
19 qdu.min(lease_min)
20 }
21}
22
23impl EvictionWatermark for StandardEngine {
24 fn watermark(&self) -> CommitVersion {
25 self.effective_gc_cutoff().min(self.consumer_watermark())
26 }
27}
28
29impl StandardEngine {
30 pub fn consumer_watermark(&self) -> CommitVersion {
31 let mut txn = match self.begin_query(IdentityId::system()) {
32 Ok(txn) => txn,
33 Err(err) => {
34 error!(error = %err, "cannot begin a query for the pinning watermark, holding cdc retention at version zero");
35 return CommitVersion(0);
36 }
37 };
38 match compute_pinning_watermark(&mut Transaction::Query(&mut txn), Some(&*self.checkpoint_floor())) {
39 Ok(Some(v)) => v,
40 Ok(None) => CommitVersion(u64::MAX),
41 Err(err) => {
42 error!(error = %err, "pinning watermark unavailable, holding cdc retention at version zero");
43 CommitVersion(0)
44 }
45 }
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use reifydb_core::{common::CommitVersion, lifecycle::watermark::QueryWatermark};
52 use reifydb_runtime::shutdown::Shutdown;
53 use reifydb_test_harness::engine::TestEngine;
54
55 #[test]
56 fn a_closed_operator_store_holds_the_consumer_watermark_at_zero_instead_of_releasing_retention() {
57 let t = TestEngine::new();
60
61 assert_eq!(
62 t.inner().consumer_watermark(),
63 CommitVersion(u64::MAX),
64 "a healthy store with no checkpoint rows pins nothing, which is what makes the closed case \
65 below a real inversion rather than a no-op"
66 );
67
68 t.inner().operator_state().shutdown().unwrap();
69
70 assert_eq!(
71 t.inner().consumer_watermark(),
72 CommitVersion(0),
73 "once the floor cannot be read the engine must hold retention at zero; answering u64::MAX \
74 here releases every cdc entry the flows have not replayed yet"
75 );
76 }
77
78 #[test]
79 fn effective_gc_cutoff_is_lowered_by_a_held_lease_and_nothing_else() {
80 let t = TestEngine::new();
83
84 let lagging = CommitVersion(50);
87 let lease = t.multi().acquire_version_lease(lagging).expect("leasing at the current head must succeed");
88
89 t.multi().advance_version_to(CommitVersion(100));
92
93 assert_eq!(
94 t.effective_gc_cutoff(),
95 lagging,
96 "a held lease must lower the historical-GC cutoff to the leased version"
97 );
98
99 drop(lease);
100 assert!(
101 t.effective_gc_cutoff().0 >= 100,
102 "with no lease held, nothing may pin the cutoff below the query watermark"
103 );
104 }
105}