d_engine_core/purge/mod.rs
1//! Log compaction and purge management.
2//!
3//! Defines the interface for customizing log purge behavior in Raft leaders and followers.
4//! Implementations can control how log entries are physically removed from storage while
5//! maintaining Raft's safety guarantees.
6
7mod default_executor;
8pub use default_executor::*;
9
10#[cfg(test)]
11mod default_executor_test;
12
13use d_engine_proto::common::LogId;
14#[cfg(any(test, feature = "test-utils"))]
15use mockall::automock;
16use tonic::async_trait;
17
18use crate::Result;
19
20/// Defines the behavior for log entry compaction and physical deletion.
21///
22/// # Safety Requirements
23/// Implementations MUST guarantee:
24/// 1. All entries up to `last_included.index` are preserved in snapshots
25/// 2. No concurrent modifications during purge execution
26/// 3. Atomic persistence of purge metadata
27#[cfg_attr(any(test, feature = "test-utils"), automock)]
28#[async_trait]
29pub trait PurgeExecutor: Send + Sync + 'static {
30 /// Physically removes log entries up to specified index (inclusive)
31 ///
32 /// # Arguments
33 /// - `last_included` The last log index included in the latest snapshot
34 ///
35 /// # Implementation Notes
36 /// - Should be atomic with updating `last_purged_index`
37 /// - Must not delete any entries required for log matching properties
38 async fn execute_purge(
39 &self,
40 last_included: LogId,
41 ) -> Result<()>;
42
43 /// Validates if purge can be safely executed
44 ///
45 /// # Key Characteristics
46 /// - **Stateless**: Does NOT validate Raft protocol state (commit index/purge order/cluster
47 /// progress)
48 /// - **Storage-focused**: Performs physical storage checks (disk space/snapshot integrity/I/O
49 /// health)
50 ///
51 /// Default implementation checks:
52 /// - No pending purge operations
53 #[allow(dead_code)]
54 async fn validate_purge(
55 &self,
56 last_included: LogId,
57 ) -> Result<()> {
58 let _ = last_included; // Default no-op
59 Ok(())
60 }
61
62 /// Lifecycle hook before purge execution
63 ///
64 /// Use for:
65 /// - Acquiring resource locks
66 /// - Starting transactions
67 #[allow(dead_code)]
68 async fn pre_purge(&self) -> Result<()> {
69 Ok(())
70 }
71
72 /// Lifecycle hook after purge execution
73 ///
74 /// Use for:
75 /// - Releasing resource locks
76 /// - Finalizing transactions
77 /// - Triggering backups
78 #[allow(unused)]
79 async fn post_purge(&self) -> Result<()> {
80 Ok(())
81 }
82}