diff --git a/examples/memstore/src/client/main.rs b/examples/memstore/src/client/main.rs index 7e5e2c8c..39e8e6c2 100644 --- a/examples/memstore/src/client/main.rs +++ b/examples/memstore/src/client/main.rs @@ -1,6 +1,4 @@ -use raftify::{ - create_client, raft_service, AbstractLogEntry -}; +use raftify::{create_client, raft_service, AbstractLogEntry}; use memstore_example_harness::state_machine::LogEntry; @@ -32,7 +30,12 @@ async fn main() { println!("Peers: {:?}", peers.into_inner().peers_json); println!("---Debug node result---"); - let result = leader_client.debug_node(raft_service::Empty {}).await.unwrap().into_inner().result_json; + let result = leader_client + .debug_node(raft_service::Empty {}) + .await + .unwrap() + .into_inner() + .result_json; println!("Debug node result: {:?}", result); @@ -68,5 +71,4 @@ async fn main() { // }, // ], // }).await.expect("Change config failed!"); - } diff --git a/raftify/Cargo.toml b/raftify/Cargo.toml index d12a6895..cfb3640c 100644 --- a/raftify/Cargo.toml +++ b/raftify/Cargo.toml @@ -9,6 +9,11 @@ description.workspace = true keywords.workspace = true readme = "../README.md" +[features] +default = ["inspection_api", "manipulation_api"] +inspection_api = [] +manipulation_api = [] + [dependencies] async-trait = "0.1.48" bincode = "1.3" diff --git a/raftify/build.rs b/raftify/build.rs index c50a10e6..025bf8a2 100644 --- a/raftify/build.rs +++ b/raftify/build.rs @@ -3,7 +3,14 @@ fn main() -> Result<(), Box> { .build_client(true) .build_server(true) .extern_path(".eraftpb", "::jopemachine_raft::eraftpb") - .compile(&["proto/raft_service.proto"], &["proto/"])?; + .compile( + &[ + "proto/raft_service.proto", + "proto/raft_inspection_service.proto", + "proto/raft_manipulation_service.proto", + ], + &["proto/"], + )?; built::write_built_file().expect("Failed to acquire build-time information"); Ok(()) diff --git a/raftify/proto/raft_inspection_service.proto b/raftify/proto/raft_inspection_service.proto new file mode 100644 index 00000000..5f957642 --- /dev/null +++ b/raftify/proto/raft_inspection_service.proto @@ -0,0 +1,48 @@ +syntax = "proto3"; +package raft_inspection_service; + +import "eraftpb.proto"; + +// TODO: Implement each methods +service RaftInspectionService { + rpc GetPendingConfChange(Empty) returns (Empty) {} + rpc GetSnapshotReport(Empty) returns (Empty) {} + rpc GetPeers(Empty) returns (Empty) {} + + // Progress + rpc GetProgressMatched(Empty) returns (Empty) {} + rpc GetProgressNextIdx(Empty) returns (Empty) {} + rpc GetProgressPaused(Empty) returns (Empty) {} + rpc GetProgressPendingSnapshot(Empty) returns (Empty) {} + rpc GetProgressPendingRequestSnapshot(Empty) returns (Empty) {} + rpc GetProgressRecentActive(Empty) returns (Empty) {} + rpc GetProgressCommitGroupId(Empty) returns (Empty) {} + rpc GetProgressInflights(Empty) returns (Empty) {} + rpc GetProgressState(Empty) returns (Empty) {} + + rpc GetNodeId(Empty) returns (Empty) {} + rpc GetLeaderId(Empty) returns (Empty) {} + rpc GetTerm(Empty) returns (Empty) {} + + // HardState + rpc GetHardStateTerm(Empty) returns (Empty) {} + rpc GetHardStateVote(Empty) returns (Empty) {} + rpc GetHardStateCommit(Empty) returns (Empty) {} + + // ConfState + rpc GetConfStateVoters(Empty) returns (Empty) {} + rpc GetConfStateLearners(Empty) returns (Empty) {} + rpc GetConfStateVotersOutgoing(Empty) returns (Empty) {} + rpc GetConfStateLearnersNext(Empty) returns (Empty) {} + rpc GetConfStateSnapshot(Empty) returns (Empty) {} + rpc GetConfStateLastIndex(Empty) returns (Empty) {} + + // RaftLog + rpc GetRaftLogCommitted(Empty) returns (Empty) {} + rpc GetRaftLogApplied(Empty) returns (Empty) {} + rpc GetRaftLogPersisted(Empty) returns (Empty) {} +} + +// Common + +message Empty {} diff --git a/raftify/proto/raft_manipulation_service.proto b/raftify/proto/raft_manipulation_service.proto new file mode 100644 index 00000000..3b1bb0d9 --- /dev/null +++ b/raftify/proto/raft_manipulation_service.proto @@ -0,0 +1,26 @@ +syntax = "proto3"; +package raft_manipulation_service; + +import "eraftpb.proto"; + +// TODO: Implement each methods +service RaftManipulationService { + rpc Campaign(Empty) returns (Empty) {} + rpc TransferLeader(Empty) returns (Empty) {} + rpc AbortTransferLeader(Empty) returns (Empty) {} + rpc Ping(Empty) returns (Empty) {} + rpc BecomeFollower(Empty) returns (Empty) {} + rpc BecomeLeader(Empty) returns (Empty) {} + rpc BecomeCandidate(Empty) returns (Empty) {} + rpc BecomePreCandidate(Empty) returns (Empty) {} + rpc RequestSnapshot(Empty) returns (Empty) {} + rpc CreateSnapshot(Empty) returns (Empty) {} + rpc IsPromotable(Empty) returns (Empty) {} + rpc CheckQuorumActive(Empty) returns (Empty) {} + rpc SendTimeoutNow(Empty) returns (Empty) {} + rpc Reset(Empty) returns (Empty) {} +} + +// Common + +message Empty {} diff --git a/raftify/src/lib.rs b/raftify/src/lib.rs index c18a70ec..e2861620 100644 --- a/raftify/src/lib.rs +++ b/raftify/src/lib.rs @@ -38,10 +38,10 @@ pub use crate::{ raft_client::create_client, raft_node::{role::InitialRole, RaftNode}, raft_service::raft_service_client::RaftServiceClient, + request::common::confchange_request::ConfChangeRequest, state_machine::AbstractStateMachine, storage::heed_storage::HeedStorage, storage::StableStorage, - request::common::confchange_request::ConfChangeRequest, }; pub(crate) use crate::utils::macros::macro_utils; diff --git a/raftify/src/raft_server.rs b/raftify/src/raft_server.rs index 8ba26b74..7775c5bb 100644 --- a/raftify/src/raft_server.rs +++ b/raftify/src/raft_server.rs @@ -15,16 +15,16 @@ use tonic::{transport::Server, Request, Response, Status}; use super::{ macro_utils::function_name, - raft_service::{ - self, - raft_service_server::{RaftService, RaftServiceServer}, - }, + raft_service::{self}, Config, Error, }; use crate::{ create_client, raft::{eraftpb::Message as RaftMessage, logger::Logger}, - raft_service::ProposeArgs, + raft_service::{ + raft_service_server::{RaftService, RaftServiceServer}, + ProposeArgs, + }, request::{ common::confchange_request::ConfChangeRequest, server_request_message::ServerRequestMsg, }, @@ -34,6 +34,12 @@ use crate::{ AbstractLogEntry, AbstractStateMachine, }; +#[cfg(feature = "inspection_api")] +use crate::raft_service::inspection_service::raft_inspection_service_server::RaftInspectionService; + +#[cfg(feature = "manipulation_api")] +use crate::raft_service::manipulation_service::raft_manipulation_service_server::RaftManipulationService; + #[derive(Clone)] pub struct RaftServer { tx: mpsc::Sender>, @@ -411,3 +417,360 @@ impl } } } + +#[cfg(feature = "manipulation_api")] +#[tonic::async_trait] +impl + RaftManipulationService for RaftServer +{ + async fn become_follower( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + todo!() + } + + async fn become_leader( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + todo!() + } + + async fn become_candidate( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + todo!() + } + + async fn become_pre_candidate( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + todo!() + } + + async fn request_snapshot( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + todo!() + } + + async fn create_snapshot( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + todo!() + } + + async fn is_promotable( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + todo!() + } + + async fn check_quorum_active( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + todo!() + } + + async fn send_timeout_now( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + todo!() + } + + async fn reset( + &self, + request: tonic::Request, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + todo!() + } + + async fn campaign( + &self, + request: Request, + ) -> Result, Status> { + todo!() + } + + async fn transfer_leader( + &self, + request: Request, + ) -> Result, Status> { + todo!() + } + + async fn abort_transfer_leader( + &self, + request: Request, + ) -> Result, Status> { + todo!() + } + + async fn ping( + &self, + request: Request, + ) -> Result, Status> { + todo!() + } +} + +#[cfg(feature = "inspection_api")] +#[tonic::async_trait] +impl + RaftInspectionService for RaftServer +{ + async fn get_pending_conf_change( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_snapshot_report( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_peers( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_progress_matched( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_progress_next_idx( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_progress_paused( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_progress_pending_snapshot( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_progress_pending_request_snapshot( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_progress_recent_active( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_progress_commit_group_id( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + // Implement the remaining missing trait items here + async fn get_progress_inflights( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_progress_state( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_node_id( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_leader_id( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_term( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_hard_state_term( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_hard_state_vote( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_hard_state_commit( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_conf_state_voters( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_conf_state_learners( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_conf_state_voters_outgoing( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_conf_state_learners_next( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_conf_state_snapshot( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_conf_state_last_index( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_raft_log_committed( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_raft_log_applied( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } + + async fn get_raft_log_persisted( + &self, + request: tonic::Request, + ) -> std::result::Result, tonic::Status> + { + todo!() + } +} diff --git a/raftify/src/raft_service.rs b/raftify/src/raft_service.rs deleted file mode 100644 index 7acc8959..00000000 --- a/raftify/src/raft_service.rs +++ /dev/null @@ -1 +0,0 @@ -tonic::include_proto!("raft_service"); diff --git a/raftify/src/raft_service/inspection_service.rs b/raftify/src/raft_service/inspection_service.rs new file mode 100644 index 00000000..0fe24ad9 --- /dev/null +++ b/raftify/src/raft_service/inspection_service.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "inspection_api")] +tonic::include_proto!("raft_inspection_service"); diff --git a/raftify/src/raft_service/manipulation_service.rs b/raftify/src/raft_service/manipulation_service.rs new file mode 100644 index 00000000..d6f6cc4a --- /dev/null +++ b/raftify/src/raft_service/manipulation_service.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "manipulation_api")] +tonic::include_proto!("raft_manipulation_service"); diff --git a/raftify/src/raft_service/mod.rs b/raftify/src/raft_service/mod.rs new file mode 100644 index 00000000..78dd8864 --- /dev/null +++ b/raftify/src/raft_service/mod.rs @@ -0,0 +1,4 @@ +pub mod inspection_service; +pub mod manipulation_service; + +tonic::include_proto!("raft_service");