diff --git a/binding/python/Makefile b/binding/python/Makefile index 5ba49126..4eed034c 100644 --- a/binding/python/Makefile +++ b/binding/python/Makefile @@ -6,25 +6,25 @@ build-release: install: maturin build - pip install . + pip install . --break-system-packages uninstall: - pip uninstall -y raftify_cli + pip uninstall -y raftify_cli --break-system-packages install-cli: cd examples/cli - pip install . + pip install . --break-system-packages cd ../.. reinstall-cli: - pip uninstall -y raftify_cli + pip uninstall -y raftify_cli --break-system-packages cd examples/cli - pip install . + pip install . --break-system-packages cd ../.. install-release: make build-release - pip install . + pip install . --break-system-packages clean: cargo clean diff --git a/binding/python/examples/main.py b/binding/python/examples/main.py index e571ee92..5742e480 100644 --- a/binding/python/examples/main.py +++ b/binding/python/examples/main.py @@ -44,10 +44,14 @@ def build_config(node_id: int, initial_peers: Peers) -> Config: election_tick=10, heartbeat_tick=3, ) + + storage_path = get_storage_path("./logs", node_id) + ensure_directory_exist(storage_path) + cfg = Config( raft_cfg, - log_dir="./logs", - compacted_log_dir="./logs", + log_dir=storage_path, + compacted_log_dir=storage_path, initial_peers=initial_peers, ) @@ -114,9 +118,6 @@ async def main(): logger = Logger(setup_logger()) store = HashStore() - storage_path = get_storage_path(cfg.log_dir, node_id) - ensure_directory_exist(storage_path) - tasks = [] raft = Raft.bootstrap(node_id, raft_addr, store, cfg, logger) tasks.append(raft.run()) diff --git a/binding/python/src/bindings/raft_bootstrapper.rs b/binding/python/src/bindings/raft_bootstrapper.rs index a2a2dc7f..79408538 100644 --- a/binding/python/src/bindings/raft_bootstrapper.rs +++ b/binding/python/src/bindings/raft_bootstrapper.rs @@ -30,7 +30,7 @@ impl PyRaftFacade { let fsm = PyFSM::new(fsm); let addr = addr.to_string(); - let storage = HeedStorage::create( + let log_storage = HeedStorage::create( &config.log_dir.clone(), &config.clone().into(), Arc::new(PyLogger::new(logger.clone())), @@ -40,7 +40,7 @@ impl PyRaftFacade { let raft = Raft::bootstrap( node_id, addr, - storage, + log_storage, fsm, config.into(), Arc::new(PyLogger::new(logger)), diff --git a/binding/python/tests/data_replication.py b/binding/python/tests/data_replication.py index 9c456594..34c899ef 100644 --- a/binding/python/tests/data_replication.py +++ b/binding/python/tests/data_replication.py @@ -1,7 +1,7 @@ import asyncio import pytest from utils import ( - ensure_directory_exist, + cleanup_storage, load_peers, wait_for_until_cluster_size_increase, ) @@ -12,7 +12,7 @@ @pytest.mark.asyncio async def test_data_replication(): - ensure_directory_exist("./logs") + cleanup_storage("./logs") peers = load_peers(THREE_NODE_EXAMPLE) asyncio.create_task(run_rafts(peers)) diff --git a/binding/python/tests/harness/raft_server.py b/binding/python/tests/harness/raft_server.py index 5076a436..5172888c 100644 --- a/binding/python/tests/harness/raft_server.py +++ b/binding/python/tests/harness/raft_server.py @@ -1,8 +1,10 @@ import asyncio from harness.state_machine import HashStore from raftify import Config, Peers, Raft, RaftConfig, Slogger +from .utils import ensure_directory_exist, get_storage_path +# All Raft objects per node ID. RAFTS: dict[int, Raft] = {} @@ -12,10 +14,14 @@ def build_config(node_id: int, initial_peers: Peers) -> Config: election_tick=10, heartbeat_tick=3, ) + + storage_path = get_storage_path("./logs", node_id) + ensure_directory_exist(storage_path) + cfg = Config( raft_cfg, - log_dir="./logs", - compacted_log_dir="./logs", + log_dir=storage_path, + compacted_log_dir=storage_path, initial_peers=initial_peers, ) diff --git a/binding/python/tests/harness/utils.py b/binding/python/tests/harness/utils.py new file mode 100644 index 00000000..543ebc0d --- /dev/null +++ b/binding/python/tests/harness/utils.py @@ -0,0 +1,10 @@ +import os + + +def get_storage_path(log_dir: str, node_id: int) -> str: + return f"{log_dir}/node-{node_id}" + + +def ensure_directory_exist(storage_path: str): + if not os.path.exists(storage_path): + os.makedirs(storage_path) diff --git a/binding/python/tests/utils.py b/binding/python/tests/utils.py index 0e08b92b..997e2534 100644 --- a/binding/python/tests/utils.py +++ b/binding/python/tests/utils.py @@ -1,5 +1,6 @@ from asyncio import sleep import os +import shutil import tomli from pathlib import Path from raftify import InitialRole, Peer, Peers, Raft @@ -48,10 +49,10 @@ async def wait_for_until_cluster_size_decrease(raft: Raft, target: int): await sleep(0.1) -def get_storage_path(log_dir: str, node_id: int) -> str: - return f"{log_dir}/node-{node_id}" +def cleanup_storage(log_dir: str): + storage_pth = log_dir + if os.path.exists(storage_pth): + shutil.rmtree(storage_pth) -def ensure_directory_exist(storage_path: str): - if not os.path.exists(storage_path): - os.makedirs(storage_path) + os.makedirs(storage_pth) diff --git a/examples/memstore/dynamic-members/src/main.rs b/examples/memstore/dynamic-members/src/main.rs index 6a6fa229..9247d62e 100644 --- a/examples/memstore/dynamic-members/src/main.rs +++ b/examples/memstore/dynamic-members/src/main.rs @@ -13,10 +13,7 @@ use slog_envlogger::LogBuilder; use std::{fs, path::Path, sync::Arc}; use structopt::StructOpt; -use example_harness::{ - config::build_config, - utils::{ensure_directory_exist, get_storage_path}, -}; +use example_harness::config::build_config; use memstore_example_harness::{ state_machine::{HashStore, LogEntry, Raft}, web_server_api::{ @@ -81,18 +78,15 @@ async fn main() -> std::result::Result<(), Box> { cfg.initial_peers = Some(ticket.peers.clone().into()); - let storage_pth = get_storage_path(cfg.log_dir.as_str(), node_id); - ensure_directory_exist(storage_pth.as_str())?; - #[cfg(feature = "inmemory_storage")] let log_storage = MemStorage::create(); #[cfg(feature = "heed_storage")] - let log_storage = HeedStorage::create(&storage_pth, &cfg.clone(), logger.clone()) + let log_storage = HeedStorage::create(&cfg.log_dir, &cfg.clone(), logger.clone()) .expect("Failed to create heed storage"); #[cfg(feature = "rocksdb_storage")] - let log_storage = RocksDBStorage::create(&storage_pth, logger.clone()) + let log_storage = RocksDBStorage::create(&cfg.log_dir, logger.clone()) .expect("Failed to create heed storage"); let raft = Raft::bootstrap( @@ -128,14 +122,12 @@ async fn main() -> std::result::Result<(), Box> { let leader_node_id = 1; let cfg = build_config(leader_node_id); - let storage_pth = get_storage_path(cfg.log_dir.as_str(), leader_node_id); - ensure_directory_exist(storage_pth.as_str())?; #[cfg(feature = "inmemory_storage")] let log_storage = MemStorage::create(); #[cfg(feature = "heed_storage")] - let log_storage = HeedStorage::create(&storage_pth, &cfg.clone(), logger.clone()) + let log_storage = HeedStorage::create(&cfg.log_dir, &cfg.clone(), logger.clone()) .expect("Failed to create heed storage"); #[cfg(feature = "rocksdb_storage")] diff --git a/examples/memstore/static-members/src/main.rs b/examples/memstore/static-members/src/main.rs index cb297685..c3600347 100644 --- a/examples/memstore/static-members/src/main.rs +++ b/examples/memstore/static-members/src/main.rs @@ -13,10 +13,7 @@ use slog_envlogger::LogBuilder; use std::sync::Arc; use structopt::StructOpt; -use example_harness::{ - config::build_config, - utils::{ensure_directory_exist, get_storage_path}, -}; +use example_harness::config::build_config; use memstore_example_harness::{ state_machine::{HashStore, LogEntry, Raft}, web_server_api::{ @@ -77,18 +74,15 @@ async fn main() -> std::result::Result<(), Box> { let mut cfg = build_config(node_id); cfg.initial_peers = Some(initial_peers.clone()); - let storage_pth = get_storage_path(cfg.log_dir.as_str(), node_id); - ensure_directory_exist(storage_pth.as_str())?; - #[cfg(feature = "inmemory_storage")] let log_storage = MemStorage::create(); #[cfg(feature = "heed_storage")] - let log_storage = HeedStorage::create(&storage_pth, &cfg.clone(), logger.clone()) + let log_storage = HeedStorage::create(&cfg.log_dir, &cfg.clone(), logger.clone()) .expect("Failed to create heed storage"); #[cfg(feature = "rocksdb_storage")] - let log_storage = RocksDBStorage::create(&storage_pth, logger.clone()) + let log_storage = RocksDBStorage::create(&cfg.log_dir, logger.clone()) .expect("Failed to create heed storage"); let raft = Raft::bootstrap( diff --git a/examples/src/config.rs b/examples/src/config.rs index 851de5e5..5423c057 100644 --- a/examples/src/config.rs +++ b/examples/src/config.rs @@ -1,18 +1,24 @@ use raftify::{Config, RaftConfig}; +use crate::utils::{ensure_directory_exist, get_storage_path}; + pub fn build_config(node_id: u64) -> Config { let raft_config = RaftConfig { id: node_id, election_tick: 10, heartbeat_tick: 3, + omit_heartbeat_log: false, ..Default::default() }; + let storage_pth = get_storage_path("./logs", node_id); + ensure_directory_exist(&storage_pth).expect("Failed to create storage directory"); + Config { tick_interval: 0.2, - log_dir: "./logs".to_owned(), + log_dir: storage_pth.clone(), save_compacted_logs: true, - compacted_log_dir: "./logs".to_owned(), + compacted_log_dir: storage_pth, compacted_log_size_threshold: 1024 * 1024 * 1024, raft_config, ..Default::default() diff --git a/harness/src/config.rs b/harness/src/config.rs index 26eb498d..af042e26 100644 --- a/harness/src/config.rs +++ b/harness/src/config.rs @@ -1,5 +1,7 @@ use raftify::{Config, RaftConfig}; +use crate::utils::{ensure_directory_exist, get_storage_path}; + pub fn build_config(node_id: u64) -> Config { let raft_config = RaftConfig { id: node_id, @@ -9,10 +11,13 @@ pub fn build_config(node_id: u64) -> Config { ..Default::default() }; + let storage_path = get_storage_path("./logs", node_id); + ensure_directory_exist(&storage_path).expect("Failed to create storage directory"); + Config { - log_dir: "./logs".to_owned(), + log_dir: storage_path.clone(), save_compacted_logs: true, - compacted_log_dir: "./logs".to_owned(), + compacted_log_dir: storage_path, compacted_log_size_threshold: 1024 * 1024 * 1024, raft_config, ..Default::default()