From 9ec8c8a0d966c2bcbc7627eab050ee6d8ec3532b Mon Sep 17 00:00:00 2001 From: Georgy Moshkin <gmoshkin@picodata.io> Date: Tue, 23 Jan 2024 15:57:45 +0300 Subject: [PATCH] feat: .proc_raft_info --- src/info.rs | 40 ++++++++++++++++++++++++++++++++++ test/int/test_basics.py | 17 +++++++++++++++ test/int/test_uninitialized.py | 1 + 3 files changed, 58 insertions(+) diff --git a/src/info.rs b/src/info.rs index f63201ff78..c5b057c461 100644 --- a/src/info.rs +++ b/src/info.rs @@ -140,3 +140,43 @@ impl crate::rpc::RequestArgs for InstanceInfoRequest { const PROC_NAME: &'static str = crate::stringify_cfunc!(proc_instance_info); type Response = InstanceInfo; } + +//////////////////////////////////////////////////////////////////////////////// +// RaftInfo +//////////////////////////////////////////////////////////////////////////////// + +#[derive(Clone, Debug, ::serde::Serialize, ::serde::Deserialize)] +pub struct RaftInfo { + pub id: RaftId, + pub term: RaftTerm, + pub applied: RaftIndex, + pub leader_id: RaftId, + pub state: node::RaftState, +} + +impl tarantool::tuple::Encode for RaftInfo {} + +impl RaftInfo { + #[inline] + pub fn get(node: &node::Node) -> Self { + let raft_status = node.status(); + RaftInfo { + id: raft_status.id, + term: raft_status.term, + applied: node.get_index(), + leader_id: raft_status.leader_id.unwrap_or(0), + state: raft_status.raft_state, + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +// .proc_raft_info +//////////////////////////////////////////////////////////////////////////////// + +#[proc] +pub fn proc_raft_info() -> Result<RaftInfo, Error> { + let node = node::global()?; + + Ok(RaftInfo::get(node)) +} diff --git a/test/int/test_basics.py b/test/int/test_basics.py index afcf32eba2..5dd78ad268 100644 --- a/test/int/test_basics.py +++ b/test/int/test_basics.py @@ -373,3 +373,20 @@ def test_proc_instance_info(cluster: Cluster): with pytest.raises(TarantoolError) as e: i1.call(".proc_instance_info", "i3") assert 'instance with id "i3" not found' in str(e) + + +def test_proc_raft_info(instance: Instance): + info = instance.call(".proc_raft_info") + + assert isinstance(info["applied"], int) + # This field is super volatile, don't want to be updating it every time we + # add a bootstrap entry. + info["applied"] = 69 + + assert info == dict( + id=1, + term=2, + applied=69, + leader_id=1, + state="Leader", + ) diff --git a/test/int/test_uninitialized.py b/test/int/test_uninitialized.py index 3b996649fa..a59eaa64ee 100644 --- a/test/int/test_uninitialized.py +++ b/test/int/test_uninitialized.py @@ -31,6 +31,7 @@ def uninitialized_instance(cluster: Cluster) -> Generator[Instance, None, None]: def test_raft_api(uninitialized_instance: Instance): functions: list[Callable[[Instance], Any]] = [ lambda i: i._raft_status(), + lambda i: i.call(".proc_raft_info"), lambda i: i.raft_get_index(), lambda i: i.raft_read_index(), lambda i: i.raft_wait_index(0), -- GitLab