Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/psiace/riteraft
RiteRaft - A raft framework, for regular people
https://github.com/psiace/riteraft
distributed distributed-systems raft raft-framework rust
Last synced: 3 days ago
JSON representation
RiteRaft - A raft framework, for regular people
- Host: GitHub
- URL: https://github.com/psiace/riteraft
- Owner: PsiACE
- License: apache-2.0
- Created: 2021-03-23T15:27:36.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2024-02-18T02:30:07.000Z (11 months ago)
- Last Synced: 2024-12-23T12:14:46.539Z (10 days ago)
- Topics: distributed, distributed-systems, raft, raft-framework, rust
- Language: Rust
- Homepage:
- Size: 61.5 KB
- Stars: 321
- Watchers: 5
- Forks: 22
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# RiteRaft - A raft framework, for regular people
This is an attempt to create a layer on top of
[tikv/raft-rs](https://github.com/tikv/raft-rs), that is easier to use and
implement. This is not supposed to be the most featureful raft, but instead a
convenient interface to get started quickly, and have a working raft in no
time.The interface is strongly inspired by the one used by [canonical/raft](https://github.com/canonical/raft).
## Getting started
In order to "raft" storage, we need to implement the `Storage` trait for it.
Bellow is an example with `HashStore`, which is a thread-safe wrapper around an
`HashMap`:```rust
/// convienient data structure to pass Message in the raft
#[derive(Serialize, Deserialize)]
pub enum Message {
Insert { key: u64, value: String },
}#[derive(Clone)]
struct HashStore(Arc>>);impl Store for HashStore {
type Error = RaftError;fn apply(&mut self, message: &[u8]) -> Result, Self::Error> {
let message: Message = deserialize(message).unwrap();
let message: Vec = match message {
Message::Insert { key, value } => {let mut db = self.0.write().unwrap();
db.insert(key, value.clone());
serialize(&value).unwrap()
}
};
Ok(message)
}fn snapshot(&self) -> Vec {
serialize(&self.0.read().unwrap().clone()).unwrap()
}fn restore(&mut self, snapshot: &[u8]) -> Result<(), Self::Error> {
let new: HashMap = deserialize(snapshot).unwrap();
let mut db = self.0.write().unwrap();
let _ = std::mem::replace(&mut *db, new);
Ok(())
}
}
```Only 3 methods need to be implemented for the Store:
- `Store::apply`: applies a commited entry to the store.
- `Store::snapshot`: returns snapshot data for the store.
- `Store::restore`: applies the snapshot passed as argument.### running the raft
```rust
#[tokio::main]
fn main() {
let store = HashStore::new();let raft = Raft::new(options.raft_addr, store.clone());
let mailbox = Arc::new(raft.mailbox());
let (raft_handle, mailbox) = match options.peer_addr {
Some(addr) => {
info!("running in follower mode");
let handle = tokio::spawn(raft.join(addr));
(handle, mailbox)
}
None => {
info!("running in leader mode");
let handle = tokio::spawn(raft.lead());
(handle, mailbox)
}
};tokio::join!(raft);
}```
The `mailbox` gives you a way to interact with the raft, for sending a message, or leaving the cluster for example.
## Credit
This work is based on [raft-frp](https://github.com/MarinPostma/raft-frp), but more adjustments and improvements have been made to the code .
## License
This library is licensed under either of:
* MIT license [LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT
* Apache License 2.0 [LICENSE-APACHE](LICENSE-APACHE) or https://opensource.org/licenses/Apache-2.0at your option.