Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/MarinPostma/raft-frp
raft, for regular people
https://github.com/MarinPostma/raft-frp
Last synced: 5 days ago
JSON representation
raft, for regular people
- Host: GitHub
- URL: https://github.com/MarinPostma/raft-frp
- Owner: MarinPostma
- Archived: true
- Created: 2020-08-12T14:41:17.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2020-10-27T08:22:33.000Z (about 4 years ago)
- Last Synced: 2024-08-03T09:12:19.432Z (4 months ago)
- Language: Rust
- Size: 87.9 KB
- Stars: 7
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# This project is not maintained anymore
# RAFT, for regular peopleThis 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::apply`: 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.