d_engine_server/api/
standalone.rs1use std::sync::Arc;
4
5use tokio::sync::watch;
6
7use crate::Result;
8#[cfg(feature = "rocksdb")]
9use crate::RocksDBStateMachine;
10#[cfg(feature = "rocksdb")]
11use crate::RocksDBStorageEngine;
12use crate::StateMachine;
13use crate::StorageEngine;
14use crate::node::NodeBuilder;
15
16pub struct StandaloneServer;
18
19impl StandaloneServer {
20 #[cfg(feature = "rocksdb")]
38 pub async fn run(shutdown_rx: watch::Receiver<()>) -> Result<()> {
39 let config = d_engine_core::RaftNodeConfig::new()?.validate()?;
40 let base_dir = std::path::PathBuf::from(&config.cluster.db_root_dir);
41
42 tokio::fs::create_dir_all(&base_dir)
43 .await
44 .map_err(|e| crate::Error::Fatal(format!("Failed to create data directory: {e}")))?;
45
46 let storage_path = base_dir.join("storage");
47 let sm_path = base_dir.join("state_machine");
48
49 tracing::info!("Starting standalone server with RocksDB at {:?}", base_dir);
50
51 let storage = Arc::new(RocksDBStorageEngine::new(storage_path)?);
52 let mut sm = RocksDBStateMachine::new(sm_path)?;
53
54 let lease_cfg = &config.raft.state_machine.lease;
56 if lease_cfg.enabled {
57 let lease = Arc::new(crate::storage::DefaultLease::new(lease_cfg.clone()));
58 sm.set_lease(lease);
59 }
60
61 let sm = Arc::new(sm);
62
63 Self::run_custom(storage, sm, shutdown_rx, None).await
64 }
65
66 #[cfg(feature = "rocksdb")]
82 pub async fn run_with(
83 config_path: &str,
84 shutdown_rx: watch::Receiver<()>,
85 ) -> Result<()> {
86 let config = d_engine_core::RaftNodeConfig::new()?
87 .with_override_config(config_path)?
88 .validate()?;
89 let base_dir = std::path::PathBuf::from(&config.cluster.db_root_dir);
90
91 tokio::fs::create_dir_all(&base_dir)
92 .await
93 .map_err(|e| crate::Error::Fatal(format!("Failed to create data directory: {e}")))?;
94
95 let storage_path = base_dir.join("storage");
96 let sm_path = base_dir.join("state_machine");
97
98 tracing::info!("Starting standalone server with RocksDB at {:?}", base_dir);
99
100 let storage = Arc::new(RocksDBStorageEngine::new(storage_path)?);
101 let mut sm = RocksDBStateMachine::new(sm_path)?;
102
103 let lease_cfg = &config.raft.state_machine.lease;
105 if lease_cfg.enabled {
106 let lease = Arc::new(crate::storage::DefaultLease::new(lease_cfg.clone()));
107 sm.set_lease(lease);
108 }
109
110 let sm = Arc::new(sm);
111
112 Self::run_custom(storage, sm, shutdown_rx, Some(config_path)).await
113 }
114
115 pub async fn run_custom<SE, SM>(
135 storage_engine: Arc<SE>,
136 state_machine: Arc<SM>,
137 shutdown_rx: watch::Receiver<()>,
138 config_path: Option<&str>,
139 ) -> Result<()>
140 where
141 SE: StorageEngine + std::fmt::Debug + 'static,
142 SM: StateMachine + std::fmt::Debug + 'static,
143 {
144 let node_config = if let Some(path) = config_path {
145 d_engine_core::RaftNodeConfig::default()
146 .with_override_config(path)?
147 .validate()?
148 } else {
149 d_engine_core::RaftNodeConfig::new()?.validate()?
150 };
151
152 let node = NodeBuilder::init(node_config, shutdown_rx)
153 .storage_engine(storage_engine)
154 .state_machine(state_machine)
155 .start()
156 .await?;
157
158 node.run().await
159 }
160}