openstack_keystone_distributed_storage/
lib.rs1use std::io;
20use std::path::Path;
21use std::sync::Arc;
22
23use fjall::Database;
24use openraft::RaftTypeConfig;
25
26pub mod app;
27pub mod grpc;
28pub mod network;
29mod proto_impl;
30mod types;
31pub mod store {
32 pub mod log_store;
33 pub mod state_machine;
34}
35
36pub use store::log_store::FjallLogStore;
37pub use store::state_machine::FjallStateMachine;
38pub use types::StoreError;
39
40pub mod protobuf {
41 pub mod api {
42 use serde::{Deserialize, Serialize};
44 tonic::include_proto!("keystone.api");
45 }
46 pub mod raft {
47 use serde::{Deserialize, Serialize};
49 tonic::include_proto!("keystone.raft");
50 }
51}
52pub use crate::protobuf as pb;
53
54openraft::declare_raft_types!(
55 pub TypeConfig:
57 D = pb::api::SetRequest,
58 R = pb::api::Response,
59 LeaderId = pb::raft::LeaderId,
60 Vote = pb::raft::Vote,
61 Entry = pb::raft::Entry,
62 Node = pb::raft::Node,
63 SnapshotData = Vec<u8>,
64);
65
66pub async fn new<C, P: AsRef<Path>>(
69 db_path: P,
70) -> Result<(FjallLogStore<C>, FjallStateMachine), io::Error>
71where
72 C: RaftTypeConfig,
73{
74 let db_path = db_path.as_ref();
75 let snapshot_dir = db_path.join("snapshots");
76 let db = Database::builder(db_path)
77 .open()
78 .map_err(|e| io::Error::other(e.to_string()))?;
79
80 let db = Arc::new(db);
81 Ok((
82 FjallLogStore::new(db.clone())?,
83 FjallStateMachine::new(db, snapshot_dir)?,
84 ))
85}
86
87#[cfg(test)]
88mod tests {
89 use std::sync::Arc;
90
91 use openraft::StorageError;
92 use openraft::testing::log::StoreBuilder;
93 use openraft::testing::log::Suite;
94 use openraft::type_config::TypeConfigExt;
95 use tempfile::TempDir;
96 use tracing_test::traced_test;
97
98 use super::TypeConfig;
99 use super::store::log_store::FjallLogStore;
100 use super::store::state_machine::FjallStateMachine;
101
102 struct FjallBuilder {}
103
104 impl StoreBuilder<TypeConfig, FjallLogStore<TypeConfig>, Arc<FjallStateMachine>, TempDir>
105 for FjallBuilder
106 {
107 async fn build(
108 &self,
109 ) -> Result<
110 (TempDir, FjallLogStore<TypeConfig>, Arc<FjallStateMachine>),
111 StorageError<TypeConfig>,
112 > {
113 let td =
114 TempDir::new().map_err(|e| StorageError::read(TypeConfig::err_from_error(&e)))?;
115 let (log_store, sm) = crate::new(td.path())
116 .await
117 .map_err(|e| StorageError::read(TypeConfig::err_from_error(&e)))?;
118 Ok((td, log_store, Arc::new(sm)))
119 }
120 }
121
122 #[test]
123 #[traced_test]
124 pub fn test_fjall_store() {
125 TypeConfig::run(async {
126 Suite::test_all(FjallBuilder {}).await.unwrap();
127 });
128 }
129}