Skip to content

Commit dc89235

Browse files
authored
feat: Implement log storage polymorphism (#82)
* WIP * Implement correct `SnapshotOutOfDate` check logic in HeedStorage * Update `apply_snapshot` in MemStorage * chore: Set default storage to heed * chore: Mark todo * fix: Use only selected storage source code * refactor: Add `LogStorage` generic type and extract log storage variable * wip * wip * wip * wip * chore: Correct dependencies * WIP * WIP - Reflect changes in python binding * chore: Remove useless debugging statement * Merge * WIP * feat: Improve error handling * fix: dynamic bootstrapping
1 parent e3bc9f4 commit dc89235

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2893
-549
lines changed

Cargo.lock

Lines changed: 25 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ default-members = [
1616
"examples/memstore/dynamic-members",
1717
"examples/memstore/static-members",
1818
]
19-
exclude = ["raft-rs"]
19+
exclude = ["raft-rs", "raftify-cli"]
2020

2121
[workspace.package]
22-
version = "0.1.69"
22+
version = "0.1.78"
2323
authors = ["Lablup Inc."]
2424
edition = "2021"
2525
description = "Experimental High level Raft framework"
@@ -35,4 +35,5 @@ example-harness = { path = "examples" }
3535
memstore-example-harness = { path = "examples/memstore" }
3636

3737
[patch.crates-io]
38-
jopemachine-raft = { path = "./raft-rs" }
38+
jopemachine-raft = { path = "./raft-rs" }
39+
raftify = { path = "./raftify" }

binding/python/Cargo.lock

Lines changed: 20 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

binding/python/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "raftify-py"
3-
version = "0.1.67"
3+
version = "0.1.78"
44
authors = ["Lablup Inc."]
55
license = "Apache-2.0"
66
repository = "https://github.com/lablup/raftify"
@@ -19,7 +19,8 @@ pyo3-asyncio = { version = "0.20.0", features = ["tokio-runtime"] }
1919
pythonize = "0.20.0"
2020
tokio = { version = "1.4", features = ["full"] }
2121
async-trait = "0.1.48"
22-
raftify = { version = "=0.1.69", default-features = false }
22+
raftify = { version = "=0.1.78", features = ["heed_storage"] , default-features = false }
23+
raftify_cli = { version = "=0.1.1" }
2324
slog = { version = "2.2", features = ["max_level_trace", "release_max_level_trace"] }
2425
slog-envlogger = "2.1.0"
2526
slog-term = "2.9.0"

binding/python/src/bindings/cli.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
use pyo3::prelude::*;
22
use pyo3_asyncio::tokio::future_into_py;
3-
use raftify::cli::cli_handler;
3+
use raftify::HeedStorage;
4+
use raftify_cli::cli_handler;
45

5-
use super::state_machine::{PyFSM, PyLogEntry};
6+
use super::abstract_types::{PyFSM, PyLogEntry};
67

78
// When args is None, std::env::args is automatically used.
89
#[pyfunction]
910
pub fn cli_main<'a>(args: Option<Vec<String>>, py: Python<'a>) -> PyResult<&'a PyAny> {
1011
future_into_py(py, async move {
11-
cli_handler::<PyLogEntry, PyFSM>(args).await.unwrap();
12+
cli_handler::<PyLogEntry, HeedStorage, PyFSM>(args)
13+
.await
14+
.unwrap();
1215
Ok(())
1316
})
1417
}

binding/python/src/bindings/config.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@ pub struct PyConfig {
1515
pub lmdb_map_size: u64,
1616
pub cluster_id: String,
1717
pub conf_change_request_timeout: f32,
18+
pub bootstrap_from_snapshot: bool,
1819
pub initial_peers: Option<PyPeers>,
1920
pub snapshot_interval: Option<f32>,
20-
pub restore_wal_from: Option<u64>,
21-
pub restore_wal_snapshot_from: Option<u64>,
2221
}
2322

2423
#[pymethods]
@@ -36,8 +35,7 @@ impl PyConfig {
3635
conf_change_request_timeout: Option<f32>,
3736
initial_peers: Option<PyPeers>,
3837
snapshot_interval: Option<f32>,
39-
restore_wal_from: Option<u64>,
40-
restore_wal_snapshot_from: Option<u64>,
38+
bootstrap_from_snapshot: Option<bool>,
4139
) -> Self {
4240
let cfg = Config::default();
4341

@@ -56,8 +54,8 @@ impl PyConfig {
5654
conf_change_request_timeout.unwrap_or(cfg.conf_change_request_timeout);
5755
let initial_peers = initial_peers;
5856
let snapshot_interval = snapshot_interval;
59-
let restore_wal_from = restore_wal_from;
60-
let restore_wal_snapshot_from = restore_wal_snapshot_from;
57+
let bootstrap_from_snapshot =
58+
bootstrap_from_snapshot.unwrap_or(cfg.bootstrap_from_snapshot);
6159

6260
Self {
6361
raft_config,
@@ -71,8 +69,7 @@ impl PyConfig {
7169
conf_change_request_timeout,
7270
initial_peers,
7371
snapshot_interval,
74-
restore_wal_from,
75-
restore_wal_snapshot_from,
72+
bootstrap_from_snapshot,
7673
}
7774
}
7875
}
@@ -91,8 +88,7 @@ impl From<PyConfig> for Config {
9188
conf_change_request_timeout: config.conf_change_request_timeout,
9289
initial_peers: config.initial_peers.map(|peers| peers.inner),
9390
raft_config: config.raft_config.inner,
94-
restore_wal_from: config.restore_wal_from,
95-
restore_wal_snapshot_from: config.restore_wal_snapshot_from,
91+
bootstrap_from_snapshot: config.bootstrap_from_snapshot,
9692
}
9793
}
9894
}

binding/python/src/bindings/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1+
pub mod abstract_types;
12
pub mod cli;
23
pub mod cluster_join_ticket;
34
pub mod confchange_request;
45
pub mod config;
56
pub mod errors;
67
pub mod formatter;
8+
pub mod initial_role;
79
pub mod logger;
810
pub mod peer;
911
pub mod peers;
1012
pub mod raft_bootstrapper;
1113
pub mod raft_client;
1214
pub mod raft_node;
1315
pub mod raft_rs;
14-
pub mod role;
1516
pub mod slogger;
16-
pub mod state_machine;
1717
pub mod utils;

binding/python/src/bindings/peer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use pyo3::prelude::*;
22
use pyo3_asyncio::tokio::future_into_py;
33
use raftify::Peer;
44

5-
use super::role::PyInitialRole;
5+
use super::initial_role::PyInitialRole;
66

77
#[derive(Clone)]
88
#[pyclass(name = "Peer")]

binding/python/src/bindings/peers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use raftify::Peers;
77
use serde::{Deserialize, Serialize};
88
use std::{collections::HashMap, hash::BuildHasherDefault};
99

10-
use super::{peer::PyPeer, role::PyInitialRole};
10+
use super::{initial_role::PyInitialRole, peer::PyPeer};
1111

1212
#[derive(Serialize, Deserialize, Clone)]
1313
#[pyclass(dict, name = "Peers")]

binding/python/src/bindings/raft_bootstrapper.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
use pyo3::{exceptions::PyException, prelude::*, types::PyString};
22
use pyo3_asyncio::tokio::future_into_py;
3-
use raftify::Raft;
3+
use raftify::{HeedStorage, Raft};
44
use std::sync::Arc;
55

66
use super::{
7+
abstract_types::{PyFSM, PyLogEntry},
78
cluster_join_ticket::PyClusterJoinTicket,
89
config::PyConfig,
910
logger::PyLogger,
1011
raft_node::PyRaftNode,
11-
state_machine::{PyFSM, PyLogEntry},
1212
};
1313

1414
#[derive(Clone)]
1515
#[pyclass(name = "Raft")]
1616
pub struct PyRaftFacade {
17-
inner: Raft<PyLogEntry, PyFSM>,
17+
inner: Raft<PyLogEntry, HeedStorage, PyFSM>,
1818
}
1919

2020
#[pymethods]
@@ -30,9 +30,17 @@ impl PyRaftFacade {
3030
let fsm = PyFSM::new(fsm);
3131
let addr = addr.to_string();
3232

33+
let storage = HeedStorage::create(
34+
&config.log_dir.clone(),
35+
&config.clone().into(),
36+
Arc::new(PyLogger::new(logger.clone())),
37+
)
38+
.expect("Failed to create heed storage");
39+
3340
let raft = Raft::bootstrap(
3441
node_id,
3542
addr,
43+
storage,
3644
fsm,
3745
config.into(),
3846
Arc::new(PyLogger::new(logger)),
@@ -49,9 +57,10 @@ impl PyRaftFacade {
4957
py: Python<'a>,
5058
) -> PyResult<&'a PyAny> {
5159
future_into_py(py, async move {
52-
let ticket = Raft::<PyLogEntry, PyFSM>::request_id(raft_addr, peer_addr.to_owned())
53-
.await
54-
.unwrap();
60+
let ticket =
61+
Raft::<PyLogEntry, HeedStorage, PyFSM>::request_id(raft_addr, peer_addr.to_owned())
62+
.await
63+
.unwrap();
5564
Ok(PyClusterJoinTicket { inner: ticket })
5665
})
5766
}

binding/python/src/bindings/raft_node.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
use pyo3::{prelude::*, types::PyString};
22
use pyo3_asyncio::tokio::future_into_py;
3-
use raftify::RaftNode;
3+
use raftify::{HeedStorage, RaftNode};
44

55
use super::{
6+
abstract_types::{PyFSM, PyLogEntry},
67
cluster_join_ticket::PyClusterJoinTicket,
8+
initial_role::PyInitialRole,
79
peers::PyPeers,
810
raft_rs::eraftpb::{conf_change_v2::PyConfChangeV2, message::PyMessage},
9-
role::PyInitialRole,
10-
state_machine::{PyFSM, PyLogEntry},
1111
};
1212

1313
#[derive(Clone)]
1414
#[pyclass(name = "RaftNode")]
1515
pub struct PyRaftNode {
16-
pub inner: RaftNode<PyLogEntry, PyFSM>,
16+
pub inner: RaftNode<PyLogEntry, HeedStorage, PyFSM>,
1717
}
1818

1919
impl PyRaftNode {
20-
pub fn new(inner: RaftNode<PyLogEntry, PyFSM>) -> Self {
20+
pub fn new(inner: RaftNode<PyLogEntry, HeedStorage, PyFSM>) -> Self {
2121
PyRaftNode { inner }
2222
}
2323
}

0 commit comments

Comments
 (0)